<route lang="json5" type="page">
{
  style: {
    navigationStyle: 'custom',
    navigationBarTitleText: '绘本阅读',
    disableScroll: true,
  },
}
</route>

<template>
  <view class="picture-book-reader" :class="{ 'landscape': isLandscape }">
    <!-- 自定义导航栏 -->
    <view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }" v-if="!isLandscape && showControls">
      <view class="navbar-content">
        <view class="navbar-left" @click="goBack">
          <uni-icons type="left" size="20" color="#333"></uni-icons>
          <text class="back-text">返回</text>
        </view>
        <view class="navbar-title">
          <text class="title-text">{{ bookTitle }}</text>
        </view>
        <view class="navbar-right">
          <!-- 导航栏右侧预留位置 -->
        </view>
      </view>
    </view>

    <!-- 绘本内容区域 -->
    <view class="book-content" :class="{ 'fullscreen': isLandscape, 'no-navbar': !isLandscape && !showControls }">
      <!-- 加载错误提示 -->
      <view v-if="loadError" class="error-container">
        <view class="error-content">
          <view class="error-icon">❌</view>
          <view class="error-title">加载失败</view>
          <view class="error-message">{{ errorMessage }}</view>
          <view class="error-actions">
            <button class="retry-btn" @click="retryLoadBookDetail">重新加载</button>
            <button class="back-btn" @click="goBack">返回</button>
          </view>
        </view>
      </view>

      <!-- 图片显示区域 -->
      <swiper v-else
        class="book-swiper"
        :current="currentPage"
        @change="onPageChange"
        :indicator-dots="false"
        :autoplay="false"
        :circular="false"
        :duration="300"
        @touchstart="onTouchStart"
        @touchend="onTouchEnd"
      >
        <swiper-item v-for="(image, index) in bookImages" :key="index">
          <view class="page-container" @click="toggleControls">
            <!-- 图片模式 -->
            <image
              v-if="readingMode === 'image'"
              class="book-page"
              :class="{
                'image-portrait': imageOrientation === 'portrait',
                'image-landscape': imageOrientation === 'landscape',
                'horizontal-image': currentImageType === 'landscape',
                'vertical-image': currentImageType === 'portrait'
              }"
              :src="image"
              mode="aspectFit"
              @load="onImageLoad"
              @error="onImageError"
            />

            <!-- 文字模式 -->
            <view v-else-if="readingMode === 'text'" class="text-reading-mode">
              <!-- 背景图片（半透明） -->
              <image
                class="background-image"
                :src="image"
                mode="aspectFit"
              />

              <!-- 文本内容区域 -->
              <view class="text-content-area">
                <view v-if="index === currentPage && currentPageText" class="text-content">
                  <view class="text-wrapper">
                    <text class="page-text">{{ currentPageText }}</text>
                  </view>
                </view>

                <!-- 无文本内容提示 -->
                <view v-else-if="index === currentPage && !currentPageText" class="no-text-tip">
                  <view class="tip-icon">📖</view>
                  <text class="tip-text">当前页面暂无文字内容</text>
                  <text class="tip-subtitle">可切换到图片模式查看</text>
                </view>
              </view>
            </view>

            <!-- 加载状态 -->
            <view class="loading" v-if="imageLoading">
              <text>加载中...</text>
            </view>
          </view>
        </swiper-item>
      </swiper>

      <!-- 页面控制栏 -->
      <view class="page-controls" v-if="!isLandscape && showControls">
        <view class="page-info">
          <text class="page-text">{{ currentPage + 1 }} / {{ totalPages }}</text>
        </view>
        <view class="control-buttons">
          <button class="control-btn" @click="prevPage" :disabled="currentPage === 0">上一页</button>
          <button class="control-btn" @click="nextPage" :disabled="currentPage === totalPages - 1">下一页</button>
        </view>
      </view>

      <!-- 横屏模式下的控制栏 -->
      <view class="landscape-controls" v-if="isLandscape && showControls">
        <!-- 左上角控制区 -->
        <view class="top-left-controls">
          <view class="control-btn" @click="goBack">
            <text class="btn-icon">←</text>
          </view>
          <view class="book-info">
            <text class="page-info">{{ currentPage + 1 }} / {{ totalPages }}</text>
            <text class="book-title-small">{{ bookTitle }}</text>
          </view>
        </view>

        <!-- 右上角控制区 -->
        <view class="top-right-controls">
          <view class="control-btn" @click="toggleSettings">
            <text class="btn-icon">⚙</text>
          </view>
          <view class="control-btn" @click="toggleFavorite">
            <text class="btn-icon">{{ isFavorite ? '♥' : '♡' }}</text>
          </view>
        </view>

        <!-- 左侧中央控制区 -->
        <view class="left-center-controls">
          <view class="control-btn large" @click="toggleAudio">
            <wd-icon v-if="isAudioPlaying" name="pause" size="30px" color="white"></wd-icon>
            <wd-icon v-else name="play" size="30px" color="white"></wd-icon>
          </view>
          <view class="control-btn large" @click="toggleReadingMode">
            <text class="btn-text">{{ readingMode === 'image' ? '图' : '文' }}</text>
          </view>
          <view class="control-btn large" :class="{ 'active': showTranslation }" v-if="isEnglishBook" @click="toggleTranslation">
            <text class="btn-text">译</text>
          </view>
        </view>

        <!-- 右侧中央控制区 -->
        <view class="right-center-controls">
          <!-- 横屏切换按钮 -->
          <view class="control-btn large" @click="toggleOrientation">
            <text class="iconfont icon-icon_hengpingqiehuan_hengpingqiehuan btn-icon"></text>
          </view>

          <view
            class="control-btn large"
            :class="{ 'loading': isTogglingAudio }"
            @click="toggleAudioSource"
          >
            <template v-if="isTogglingAudio">
              <text class="btn-icon">⏳</text>
            </template>
            <template v-else-if="audioSource === 'official'">
              <text class="iconfont icon-offical btn-icon"></text>
            </template>
            <template v-else>
              <text class="iconfont icon-geren btn-icon"></text>
            </template>
          </view>
          <view
            class="control-btn large recording-btn"
            :class="{ 'recording': recordingState === RecordingState.RECORDING, 'paused': recordingState === RecordingState.PAUSED }"
            @click="toggleRecording"
            @longpress="selectRecordingQuality"
          >
            <template v-if="recordingState === RecordingState.RECORDING">
              <wd-icon v-if="supportsPauseResume" name="pause" size="22px" color="white"></wd-icon>
              <text v-else class="btn-icon">⏹️</text>
            </template>
            <template v-else-if="recordingState === RecordingState.PAUSED">
              <wd-icon name="play" size="22px" color="white"></wd-icon>
            </template>
            <text v-else class="iconfont icon-luyin btn-icon"></text>
            <!-- <text class="btn-label">{{ getRecordingButtonLabel() }}</text> -->
          </view>


        </view>

        <!-- 底部进度条 -->
        <view class="landscape-progress">
          <view class="progress-bar">
            <view class="progress-fill" :style="{ width: progressPercent + '%' }"></view>
          </view>
        </view>

        <!-- 翻译结果显示 -->
        <view class="translation-overlay" v-if="showTranslation && translationText">
          <view class="translation-content">
            <view class="translation-header">
              <text class="translation-title">中文翻译</text>
              <view class="translation-close" @click="closeTranslation">
                <text class="close-icon">×</text>
              </view>
            </view>
            <view class="translation-text">
              <text>{{ translationText }}</text>
            </view>
          </view>
        </view>

        <!-- 翻译加载状态 -->
        <view class="translation-loading" v-if="translationLoading">
          <view class="loading-content">
            <text class="loading-text">正在翻译...</text>
          </view>
        </view>

        <!-- 录音状态覆盖层 - 优化版本 -->
        <view
          class="recording-overlay-modern"
          v-if="isRecording && recordingState !== 'completed' && recordingState !== 'idle' && recordingState !== 'error'"
          @click="handleOverlayClick"
          :data-debug="'overlay-' + overlayCounter"
          :data-state="recordingState"
          :data-recording="isRecording"
        >
          <!-- 录音状态卡片 -->
          <view class="recording-card">
            <!-- 录音波纹动画 -->
            <view class="recording-wave-container">
              <view class="recording-wave-center">
                <text class="iconfont icon-luyin recording-icon"></text>
              </view>
              <view
                class="recording-wave"
                :class="{ 'active': recordingState === RecordingState.RECORDING }"
                v-for="i in 3"
                :key="i"
                :style="{ 'animation-delay': (i - 1) * 0.5 + 's' }"
              ></view>
            </view>

            <!-- 录音信息 -->
            <view class="recording-info">
              <text class="recording-status">{{ getRecordingStateDescription(recordingState) }}</text>
              <text class="recording-time">{{ getFormattedRecordingDuration() }}</text>
            </view>

            <!-- 录音控制按钮 - 简化版 -->
            <view class="recording-controls-mini">
              <!-- 暂停/恢复按钮 -->
              <view
                v-if="recordingState === RecordingState.RECORDING && supportsPauseResume"
                class="control-btn-mini pause"
                @click.stop="pauseRecording"
              >
                <wd-icon name="pause" size="22px" color="white"></wd-icon>
              </view>

              <view
                v-if="recordingState === RecordingState.PAUSED && supportsPauseResume"
                class="control-btn-mini resume"
                @click.stop="resumeRecording"
              >
                <wd-icon name="play" size="22px" color="white"></wd-icon>
              </view>

              <!-- 停止按钮 -->
              <view
                class="control-btn-mini stop"
                @click.stop="handleOverlayStopClick"
              >
                <text class="btn-icon-mini">⏹️</text>
              </view>
            </view>
          </view>
        </view>

        <!-- 录音预览界面 -->
        <view
          class="recording-preview-overlay"
          v-if="showRecordingPreview"
          @click="handlePreviewOverlayClick"
        >
          <view class="preview-card">
            <!-- 预览标题 -->
            <view class="preview-header">
              <text class="preview-title">录音预览</text>
              <text class="preview-duration">{{ getFormattedRecordingDuration() }}</text>
            </view>

            <!-- 预览控制 -->
            <view class="preview-controls">
              <!-- 播放/暂停按钮 -->
              <view
                class="preview-btn play-btn"
                :class="{ 'playing': isPreviewPlaying }"
                @click="togglePreviewPlayback"
              >
                <wd-icon v-if="isPreviewPlaying" name="pause" size="22px"></wd-icon>
                <wd-icon v-else name="play" size="22px"></wd-icon>
                <text class="btn-text">{{ isPreviewPlaying ? '暂停' : '播放' }}</text>
              </view>

              <!-- 重新录制按钮 -->
              <view
                class="preview-btn rerecord-btn"
                @click="rerecordFromPreview"
              >
                <text class="iconfont icon-luyin btn-icon"></text>
                <text class="btn-text">重录</text>
              </view>
            </view>

            <!-- 预览操作 -->
            <view class="preview-actions">
              <!-- 取消按钮 -->
              <view
                class="action-btn cancel-btn"
                @click="cancelRecordingPreview"
              >
                <text class="action-text">取消</text>
              </view>

              <!-- 确认上传按钮 -->
              <view
                class="action-btn confirm-btn"
                @click="confirmRecordingUpload"
              >
                <text class="action-text">确认上传</text>
              </view>
            </view>
          </view>
        </view>
      </view>

      <!-- 操作提示 -->
      <view class="reading-tip" v-if="showTip && isLandscape" @click="hideTip">
        <view class="tip-content">
          <text class="tip-text">左右滑动翻页，点击图片隐藏控制栏</text>
          <text class="tip-close">点击关闭</text>
        </view>
      </view>

      <!-- 自动阅读下一本对话框 -->
      <view class="next-book-dialog" v-if="showNextBookDialog">
        <view class="dialog-overlay" @click="cancelAutoReadNext"></view>
        <view class="dialog-content">
          <view class="dialog-header">
            <text class="dialog-title">准备阅读下一本</text>
          </view>
          <view class="dialog-body">
            <view class="next-book-info" v-if="nextBook">
              <image class="next-book-cover" :src="nextBook.cover" mode="aspectFit" />
              <view class="next-book-details">
                <text class="next-book-title">{{ nextBook.title }}</text>
                <text class="next-book-desc" v-if="nextBook.description">{{ nextBook.description }}</text>
              </view>
            </view>
            <view class="countdown-info">
              <text class="countdown-text">{{ nextBookCountdown }} 秒后自动开始</text>
            </view>
          </view>
          <view class="dialog-actions">
            <button class="dialog-btn cancel-btn" @click="cancelAutoReadNext">取消</button>
            <button class="dialog-btn confirm-btn" @click="confirmAutoReadNext">立即开始</button>
          </view>
        </view>
      </view>

      <!-- 阅读完成选择对话框 -->
      <view class="reading-complete-dialog" v-if="showReadingCompleteDialog">
        <view class="dialog-overlay" @click="closeReadingCompleteDialog"></view>
        <view class="dialog-content">
          <view class="dialog-header">
            <text class="dialog-title">🎉 绘本阅读完成</text>
          </view>
          <view class="dialog-body">
            <text class="complete-message">恭喜您完成了《{{ bookTitle }}》的阅读！</text>
            <text class="complete-subtitle">您希望接下来做什么？</text>
          </view>
          <view class="dialog-actions vertical">
            <!-- 阅读下一本按钮（仅在有下一本时显示） -->
            <button
              v-if="hasNextBook"
              class="dialog-btn primary-btn"
              @click="chooseReadNext"
            >
              📖 阅读下一本
            </button>
            <!-- 重新阅读按钮 -->
            <button class="dialog-btn secondary-btn" @click="chooseReread">
              🔄 重新阅读
            </button>
            <!-- 退出阅读按钮 -->
            <button class="dialog-btn cancel-btn" @click="chooseExit">
              🏠 退出阅读
            </button>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script lang="ts" setup>
import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue'
import { onLoad, onShow, onHide } from '@dcloudio/uni-app'
import { useUserStore } from '@/store/user'
import { getPictureBookDetail, getBookAudio, getUserRecordings, saveReadingRecord, getReadingRecord } from '@/api'
import { addBookFavorite, removeBookFavorite, checkBookFavoriteStatus, translateText, getTranslationHistory, getBookSetDetail } from '@/api/book'
import { clearFavoritesCache } from '@/api/favorites'
import { checkExistingRecording, uploadRecording, getUserRecordingByPage } from '@/api/recording'
import { completeAssignment } from '@/api/assignments'
import { http } from '@/utils/request'
import type { PictureBookDetailRespVO, BookPageRespVO, AudioResourceRespVO, UserRecordingRespVO, ReadingRecordCreateReqVO, FavoriteOperationReqVO, BookSetDetailRespVO, PictureBookRespVO } from '@/api'
import type { ApiResponse } from '@/api/types/common'
import type { UserSettingsRespVO, UserSettingsUpdateReqVO } from '@/api/types/user'

// 备用API函数定义（解决导入问题）
const getUserSettings = () => {
  return http.get<ApiResponse<UserSettingsRespVO>>('/reading/user/settings')
}

const updateUserSettings = (data: UserSettingsUpdateReqVO) => {
  return http.put<ApiResponse<boolean>>('/reading/user/settings', data)
}

// 页面状态
const statusBarHeight = ref(0)
const isLandscape = ref(true) // 默认横屏显示
const currentPage = ref(0)
const bookTitle = ref('')
const bookId = ref('')
const planId = ref('') // 计划ID
const taskId = ref('') // 任务ID
const assignmentId = ref('') // 作业ID
const requirementType = ref('') // 作业要求类型 (audio/read)
const fromAssignment = ref(false) // 是否来自作业
const isTeacher = ref(false) // 是否为老师（作业创建者）
const imageLoading = ref(false)
const showControls = ref(true)
const showTip = ref(true)

// 控制状态
const isFavorite = ref(false)
const readingMode = ref('image') // 'image' 或 'text'
const isEnglishBook = ref(true) // 是否为英文书籍
const isAudioPlaying = ref(false)
const audioSource = ref('official') // 'official' 官方音频 | 'user' 用户录制音频

// 音频切换状态（防止重复点击）
const isTogglingAudio = ref(false)

// 阅读时长跟踪
const readingStartTime = ref(0) // 开始阅读时间戳
const totalReadingTime = ref(0) // 总阅读时长（秒）
const pageStartTime = ref(0) // 当前页面开始时间

// 防止重复保存阅读记录的标志位
const isSavingFinalRecord = ref(false)

// 阅读设置（与用户设置页面保持一致）
const readingSettings = ref({
  readingMode: 'image',
  autoTurnPage: false,
  autoTurnPageInterval: 10, // 统一使用autoTurnPageInterval
  autoPlayAudio: true,
  autoTurnAfterAudio: true,
  autoReadNext: false,
  // 其他设置字段（从用户设置页面同步）
  showPinyin: false,
  showTranslation: false,
  fontSize: 16,
  enablePushNotification: true,
  enableReadingReminder: false,
  readingReminderTime: '19:00',
  enablePlanReminder: true,
  profilePublic: false,
  readingHistoryPublic: false,
  allowFollow: true,
  language: 'zh',
  theme: 'auto',
  soundEffects: true,
  vibration: true,
})

// 自动翻页定时器
let autoTurnTimer: any = null
// 音频播放定时器
let audioTimer: any = null
// 是否正在播放音频
let isAudioActive = false
// 当前音频上下文
let currentAudioContext: any = null
// 音频播放防抖定时器
let audioPlayDebounceTimer: any = null
// 音频控制防抖定时器
let audioControlDebounceTimer: any = null
// 用户是否手动暂停了音频（用于区分用户主动暂停和系统自动暂停）
let userManuallyStopped = false
// 控制栏自动隐藏定时器
let controlsAutoHideTimer: any = null
// 用户操作状态跟踪
const isUserOperating = ref(false)
let userOperationTimer: any = null
const USER_OPERATION_TIMEOUT = 500 // 用户停止操作后500ms认为操作结束

// 绘本数据
const bookDetail = ref<PictureBookDetailRespVO | null>(null)
const bookPages = ref<BookPageRespVO[]>([])
const bookImages = ref<string[]>([])
const audioResources = ref<AudioResourceRespVO[]>([])
const userRecordings = ref<UserRecordingRespVO[]>([])

// 绘本集相关数据
const bookSetDetail = ref<BookSetDetailRespVO | null>(null)
const bookSetBooks = ref<PictureBookRespVO[]>([])
const currentBookIndex = ref(-1)

// 自动阅读下一本相关状态
const showNextBookDialog = ref(false)
const nextBookCountdown = ref(3)
const nextBookTimer = ref<number | null>(null)
const nextBook = ref<PictureBookRespVO | null>(null)

// 阅读完成选择对话框状态
const showReadingCompleteDialog = ref(false)
const isRereading = ref(false) // 标记是否为重新阅读模式

// 加载状态
const loading = ref(false)
const audioLoading = ref(false)
const loadError = ref(false)
const errorMessage = ref('')

// 音频资源缓存
const audioCache = new Map<string, AudioResourceRespVO[]>()

// 阅读记录离线队列
const offlineReadingRecords = ref<ReadingRecordCreateReqVO[]>([])

// 翻译功能状态
const showTranslation = ref(false)
const translationText = ref('')
const translationLoading = ref(false)
const translationCache = new Map<string, string>()

// 录音功能状态
const isRecording = ref(false)
const recordingDuration = ref(0)
const recordingTimer = ref<number | null>(null)
const recorderManager = ref<UniApp.RecorderManager | null>(null)

// 录音预览状态
const showRecordingPreview = ref(false)
const previewRecordingData = ref<any>(null)
const isPreviewPlaying = ref(false)
const previewAudioContext = ref<any>(null)

// 监听录音状态变化
watch(isRecording, (newVal, oldVal) => {
  console.log('🔍 isRecording 状态变化:', oldVal, '->', newVal)
})

const recordingPaused = ref(false)
const recordingQuality = ref<'low' | 'medium' | 'high'>('medium')

// 录音权限管理
const recordingPermissionStatus = ref<'unknown' | 'granted' | 'denied' | 'checking' | 'temporarily_denied'>('unknown')
const permissionCheckRetryCount = ref(0)
const maxPermissionRetries = 3
const permissionCheckInProgress = ref(false)

// 录音状态枚举
enum RecordingState {
  IDLE = 'idle',
  PREPARING = 'preparing',
  RECORDING = 'recording',
  PAUSED = 'paused',
  STOPPING = 'stopping',
  PROCESSING = 'processing',
  PREVIEW = 'preview',
  COMPLETED = 'completed',
  ERROR = 'error'
}

// 录音权限错误类型
enum RecordingPermissionError {
  DENIED = 'denied',
  TEMPORARILY_DENIED = 'temporarily_denied',
  SYSTEM_ERROR = 'system_error',
  UNKNOWN = 'unknown'
}

// 录音状态管理
const recordingState = ref<RecordingState>(RecordingState.IDLE)
const recordingStartTime = ref(0)
const recordingFilePath = ref('')
const recordingFileSize = ref(0)

// 监听录音状态变化
watch(recordingState, (newVal, oldVal) => {
  console.log('🔍 recordingState 状态变化:', oldVal, '->', newVal)
})

// 临时录音存储（只保存当前页面最新录音）
const currentPageRecording = ref<{
  filePath: string
  duration: number
  quality: string
  createTime: string
  bookId: number
  pageNumber: number
} | null>(null)

// 服务器端用户录音数据
const serverUserRecording = ref<{
  id: number
  audioUrl: string
  duration: number
  recordingQuality?: string
} | null>(null)

// 录音上传状态
const uploadingRecordings = ref<Set<string>>(new Set())
const uploadQueue = ref<Array<{
  id: string
  filePath: string
  bookId: string
  pageNumber: number
  priority: number
}>>([])
const isUploading = ref(false)

// 音量监控
const currentVolumeLevel = ref(0)
const volumeMonitorTimer = ref<number | null>(null)
const volumeHistory = ref<number[]>([])
const maxVolumeHistory = 50 // 保留最近50个音量值

// 质量管理
const qualityRecommendation = ref<{
  recommended: 'low' | 'medium' | 'high'
  reason: string
  confidence: number
  factors: string[]
} | null>(null)

// 设备性能信息
const devicePerformance = ref({
  memoryLevel: 'unknown', // 'low' | 'medium' | 'high' | 'unknown'
  storageAvailable: 0,
  networkSpeed: 'unknown', // 'slow' | 'medium' | 'fast' | 'unknown'
  batteryLevel: 100,
  isCharging: false
})

// 错误处理和用户反馈
const errorHistory = ref<Array<{
  id: string
  type: string
  message: string
  details: any
  timestamp: string
  resolved: boolean
  userAction?: string
}>>([])

const feedbackQueue = ref<Array<{
  id: string
  type: 'success' | 'warning' | 'error' | 'info'
  title: string
  message: string
  duration: number
  actions?: Array<{ text: string, action: () => void }>
}>>([])

const currentFeedback = ref<any>(null)
const maxErrorHistory = 50 // 最多保留50个错误记录

// 错误类型定义
enum ErrorType {
  PERMISSION_DENIED = 'permission_denied',
  NETWORK_ERROR = 'network_error',
  STORAGE_ERROR = 'storage_error',
  AUDIO_ERROR = 'audio_error',
  RECORDING_ERROR = 'recording_error',
  FILE_ERROR = 'file_error',
  SYSTEM_ERROR = 'system_error',
  USER_ERROR = 'user_error'
}

// 性能监控
const performanceMetrics = ref({
  recordingLatency: 0, // 录音启动延迟
  audioLoadTime: 0, // 音频加载时间
  memoryUsage: 0, // 内存使用量
  cpuUsage: 0, // CPU使用率
  batteryDrain: 0, // 电池消耗
  frameDrops: 0, // 帧丢失
  networkLatency: 0, // 网络延迟
  storageIOTime: 0 // 存储IO时间
})

const performanceHistory = ref<Array<{
  timestamp: string
  metrics: typeof performanceMetrics.value
  operation: string
}>>([])

const performanceConfig = {
  monitoringEnabled: false, // 暂时禁用性能监控，避免API兼容性问题
  sampleInterval: 5000, // 5秒采样一次
  maxHistorySize: 100, // 最多保留100个性能记录
  alertThresholds: {
    memoryUsage: 80, // 内存使用率超过80%时警告
    batteryDrain: 10, // 电池消耗超过10%/小时时警告
    recordingLatency: 2000, // 录音延迟超过2秒时警告
    audioLoadTime: 5000 // 音频加载超过5秒时警告
  }
}

// 性能监控定时器
const performanceMonitorTimer = ref<number | null>(null)
const batteryMonitorTimer = ref<number | null>(null)

// 电池优化
const batteryOptimization = ref({
  enabled: true,
  lowPowerMode: false,
  backgroundProcessing: true,
  qualityAdjustment: true,
  uploadThrottling: true
})

// 检查是否支持暂停和恢复功能
const supportsPauseResume = computed(() => {
  // 现在启用暂停/恢复功能
  return recorderManager.value &&
         typeof recorderManager.value.pause === 'function' &&
         typeof recorderManager.value.resume === 'function'
})



// 覆盖层计数器（用于调试）
const overlayCounter = ref(0)

// 响应式检查是否有用户录音（检查服务器端录音或临时录音）
const hasUserRecordingComputed = computed(() => {
  // 优先检查服务器端录音
  if (serverUserRecording.value !== null) {
    return true
  }
  // 其次检查临时录音
  return currentPageRecording.value !== null &&
         currentPageRecording.value.bookId === Number(bookId.value) &&
         currentPageRecording.value.pageNumber === currentPage.value
})

// 计算属性：当前图片显示信息
const currentImageDisplayInfo = computed(() => {
  return {
    imageType: currentImageType.value,
    displayOrientation: imageOrientation.value,
    aspectRatio: imageInfo.value.aspectRatio,
    dimensions: `${imageInfo.value.width}x${imageInfo.value.height}`,
    isHorizontalImage: currentImageType.value === 'landscape',
    isVerticalImage: currentImageType.value === 'portrait'
  }
})

// 计算属性：是否应该显示录音覆盖层
const shouldShowRecordingOverlay = computed(() => {
  // 不显示覆盖层的状态
  const inactiveStates = [
    RecordingState.IDLE,
    RecordingState.COMPLETED,
    RecordingState.ERROR
  ]

  // 如果正在录音，或者录音状态不是非活跃状态，就显示覆盖层
  const shouldShow = isRecording.value || !inactiveStates.includes(recordingState.value)

  console.log('🔍 覆盖层显示计算:', {
    isRecording: isRecording.value,
    recordingState: recordingState.value,
    inactiveStates: inactiveStates,
    shouldShow: shouldShow,
    timestamp: Date.now()
  })

  return shouldShow
})

// 监听覆盖层显示状态变化（已移除以避免递归更新）
// watch(shouldShowRecordingOverlay, (newVal, oldVal) => {
//   console.log('🔍 覆盖层显示状态变化:', oldVal, '->', newVal)
//   if (newVal) {
//     console.log('✅ 覆盖层应该显示')
//   } else {
//     console.log('❌ 覆盖层应该隐藏')
//   }
// })



// 强制刷新覆盖层状态
function forceRefreshOverlay() {
  console.log('🔄 强制刷新覆盖层状态')
  console.log('🔍 当前状态 - isRecording:', isRecording.value, 'recordingState:', recordingState.value)
  console.log('🔍 覆盖层应该显示:', shouldShowRecordingOverlay.value)

  // 如果录音已完成但覆盖层仍显示，强制隐藏
  if (recordingState.value === RecordingState.COMPLETED || recordingState.value === RecordingState.ERROR) {
    console.log('🔄 录音已完成，强制重置状态')
    isRecording.value = false
    recordingState.value = RecordingState.IDLE
  }
}

// 录音配置
const recordingConfig = {
  low: {
    sampleRate: 8000,
    numberOfChannels: 1,
    encodeBitRate: 32000,
    format: 'mp3',
    maxDuration: 60000, // 1分钟
    description: '低质量 (节省空间)'
  },
  medium: {
    sampleRate: 16000,
    numberOfChannels: 1,
    encodeBitRate: 96000,
    format: 'mp3',
    maxDuration: 60000, // 1分钟
    description: '标准质量 (推荐)'
  },
  high: {
    sampleRate: 44100,
    numberOfChannels: 2,
    encodeBitRate: 192000,
    format: 'mp3',
    maxDuration: 60000, // 1分钟
    description: '高质量 (占用空间大)'
  }
}

// 录音存储配置
const recordingStorageConfig = {
  storageKey: 'userRecordings',
  backupToCloud: false
}

// 音频播放进度控制
const audioProgress = ref(0) // 当前播放进度 (0-100)
const audioDuration = ref(0) // 音频总时长 (秒)
const audioCurrentTime = ref(0) // 当前播放时间 (秒)
const audioProgressTimer = ref<number | null>(null)

// 验证并修正阅读记录数据
function validateReadingRecord(record: ReadingRecordCreateReqVO): ReadingRecordCreateReqVO {
  // 修正无效的阅读模式值
  let validReadingMode = record.readingMode || 'image'
  if (!['image', 'text'].includes(validReadingMode)) {
    console.warn(`⚠️ 无效的阅读模式 "${validReadingMode}"，已修正为 "image"`)
    validReadingMode = 'image'
  }

  return {
    bookId: Number(record.bookId) || 0,
    planId: record.planId ? Number(record.planId) : undefined,
    lastPage: Number(record.lastPage) || 1,
    readingProgress: Number(record.readingProgress) || 0,
    readingTime: Number(record.readingTime) || 0,
    readingMode: validReadingMode,
    isCompleted: Boolean(record.isCompleted)
  }
}

// 从本地存储加载离线记录
function loadOfflineRecords() {
  try {
    const saved = uni.getStorageSync('offlineReadingRecords')
    if (saved && Array.isArray(saved)) {
      // 验证并修正所有离线记录
      const validatedRecords = saved.map(record => validateReadingRecord(record))
      offlineReadingRecords.value = validatedRecords

      // 如果有记录被修正，重新保存
      if (JSON.stringify(saved) !== JSON.stringify(validatedRecords)) {
        console.log('🔧 检测到无效的离线记录，已自动修正')
        saveOfflineRecords()
      }

      console.log('已加载离线阅读记录:', validatedRecords.length, '条')
    }
  } catch (error) {
    console.error('加载离线记录失败:', error)
    offlineReadingRecords.value = []
  }
}

// 清理本地存储中的无效数据
function cleanupLocalStorage() {
  try {
    // 清理阅读设置中的无效阅读模式
    const savedSettings = uni.getStorageSync('readingSettings')
    if (savedSettings && savedSettings.readingMode) {
      if (!['image', 'text'].includes(savedSettings.readingMode)) {
        console.log('🔧 清理无效的阅读设置:', savedSettings.readingMode)
        savedSettings.readingMode = 'image'
        uni.setStorageSync('readingSettings', savedSettings)
      }
    }

    console.log('✅ 本地存储清理完成')
  } catch (error) {
    console.error('清理本地存储失败:', error)
  }
}

// 手动清理所有无效的离线记录
function clearInvalidOfflineRecords() {
  try {
    const validRecords = offlineReadingRecords.value.filter(record => {
      const validated = validateReadingRecord(record)
      return ['image', 'text'].includes(validated.readingMode)
    })

    const removedCount = offlineReadingRecords.value.length - validRecords.length

    if (removedCount > 0) {
      offlineReadingRecords.value = validRecords
      saveOfflineRecords()
      console.log(`🗑️ 已清理 ${removedCount} 条无效的离线记录`)

      uni.showToast({
        title: `已清理${removedCount}条无效记录`,
        icon: 'success'
      })
    } else {
      console.log('✅ 没有发现无效的离线记录')
      uni.showToast({
        title: '没有无效记录',
        icon: 'none'
      })
    }
  } catch (error) {
    console.error('清理无效离线记录失败:', error)
    uni.showToast({
      title: '清理失败',
      icon: 'error'
    })
  }
}

// 从本地存储加载翻译缓存
function loadTranslationCache() {
  try {
    const translations = uni.getStorageSync('translations') || {}
    Object.entries(translations).forEach(([key, value]) => {
      if (typeof value === 'string') {
        translationCache.set(key, value)
      }
    })
    console.log(`翻译缓存加载完成: ${translationCache.size}条记录`)
  } catch (error) {
    console.error('加载翻译缓存失败:', error)
  }
}

// 保存离线记录到本地存储
function saveOfflineRecords() {
  try {
    uni.setStorageSync('offlineReadingRecords', offlineReadingRecords.value)
  } catch (error) {
    console.error('保存离线记录失败:', error)
  }
}

// 同步离线记录到服务器
async function syncOfflineRecords() {
  if (offlineReadingRecords.value.length === 0) return

  console.log(`开始同步${offlineReadingRecords.value.length}条离线阅读记录`)

  const recordsToSync = [...offlineReadingRecords.value]
  const syncedRecords: ReadingRecordCreateReqVO[] = []

  for (const record of recordsToSync) {
    try {
      // 确保记录数据的完整性
      const validatedRecord = validateReadingRecord(record)

      console.log('🔄 正在同步离线记录:', {
        bookId: validatedRecord.bookId,
        readingMode: validatedRecord.readingMode,
        lastPage: validatedRecord.lastPage,
        readingProgress: validatedRecord.readingProgress
      })

      const response = await saveReadingRecord(validatedRecord)
      if (response && response.code === 0) {
        syncedRecords.push(record)
        console.log('✅ 离线记录同步成功')
      } else {
        console.error('❌ 离线记录同步失败，服务器响应:', response)
        throw new Error(response?.msg || '服务器返回错误')
      }
    } catch (error) {
      console.error('❌ 离线记录同步失败:', {
        record: record,
        error: error,
        errorMessage: error instanceof Error ? error.message : String(error)
      })
      break // 遇到错误停止同步，避免重复失败
    }
  }

  // 移除已同步的记录
  if (syncedRecords.length > 0) {
    offlineReadingRecords.value = offlineReadingRecords.value.filter(
      record => !syncedRecords.includes(record)
    )
    saveOfflineRecords()
    console.log(`成功同步${syncedRecords.length}条离线记录`)
  }
}



// 计算属性
const totalPages = computed(() => bookImages.value.length)
const progressPercent = computed(() => {
  if (totalPages.value === 0) return 0
  return ((currentPage.value + 1) / totalPages.value) * 100
})

// 当前页面文本内容
const currentPageText = computed(() => {
  const currentPageData = bookPages.value[currentPage.value]

  // 如果显示翻译且有翻译内容，则显示翻译
  if (showTranslation.value && currentPageData?.chineseTranslation) {
    return currentPageData.chineseTranslation
  }

  // 否则显示原文
  return currentPageData?.textContent || ''
})

// 当前页面是否有文本内容
const hasCurrentPageText = computed(() => {
  return currentPageText.value.trim().length > 0
})

// 是否有下一本绘本
const hasNextBook = computed(() => {
  if (!bookSetDetail.value || bookSetBooks.value.length === 0) {
    return false
  }
  const nextBookIndex = currentBookIndex.value + 1
  return nextBookIndex < bookSetBooks.value.length
})

// API调用函数
async function loadBookDetail(id: string) {
  try {
    loading.value = true
    imageLoading.value = true
    loadError.value = false
    errorMessage.value = ''

    // 显示加载提示
    uni.showLoading({
      title: '加载绘本中...',
      mask: true
    })

    const response = await getPictureBookDetail(Number(id))

    // 检查响应是否有效
    if (response && response.code === 0) {
      bookDetail.value = response.data
      bookTitle.value = bookDetail.value.title || '未知绘本'

      console.log('📚 绘本详情数据:', bookDetail.value)

      // 处理页面数据，支持 pageList 和 pages 两种字段名
      const pages = (bookDetail.value as any).pageList || bookDetail.value.pages
      if (Array.isArray(pages)) {
        bookPages.value = pages
        console.log('📄 绘本页面数据:', pages.length, '页')

        // 检查第一页的音频数据
        if (pages.length > 0) {
          const firstPage = pages[0]
          console.log('🎵 第一页音频数据检查:', {
            pageNumber: firstPage.pageNumber,
            officialAudioUrl: firstPage.officialAudioUrl,
            audioDuration: firstPage.audioDuration,
            hasOfficialAudio: !!firstPage.officialAudioUrl
          })
        }
      } else {
        console.warn('⚠️ 绘本页面数据不是数组:', pages, '类型:', typeof pages)
        bookPages.value = []
      }

      // 提取页面图片，支持多种字段名
      bookImages.value = bookPages.value.map(page => {
        // 尝试不同的图片字段名
        const pageAny = page as any
        return page.imageUrl || pageAny.image || pageAny.url || pageAny.src || ''
      }).filter(url => url)

      console.log('🖼️ 提取到图片:', bookImages.value.length, '张')
      console.log('📄 第一页数据示例:', bookPages.value[0])

      // 验证图片数量
      if (bookImages.value.length === 0) {
        throw new Error('绘本页面数据为空')
      }

      // 加载音频资源
      await loadAudioResources(id)

      // 检查收藏状态
      await checkFavoriteStatus()

      // 加载绘本集信息（用于自动阅读下一本功能）
      await loadBookSetInfo()

      // 隐藏加载提示
      uni.hideLoading()

      // 加载当前页面的用户录音
      await loadCurrentPageUserRecording()

      // 检查并自动切换音频模式
      await checkAndSwitchAudioMode()

      // 如果来自作业，显示作业状态提示
      if (fromAssignment.value) {
        setTimeout(async () => {
          showAssignmentStatusHint()

          // 如果是配音作业且非老师，显示当前录音进度
          if (requirementType.value === 'audio' && !isTeacher.value) {
            setTimeout(async () => {
              const recordedCount = await getRecordedPagesCount()
              const totalPages = bookPages.value.length
              if (recordedCount > 0) {
                uni.showToast({
                  title: `当前进度: ${recordedCount}/${totalPages} 页已录音`,
                  icon: 'none',
                  duration: 2000
                })
              }
            }, 3500) // 在作业提示后显示进度
          }
        }, 1000) // 延迟1秒显示，避免与其他提示冲突
      }
    } else {
      const errorMsg = response?.msg || 'API响应格式异常'
      console.warn('绘本详情API响应异常:', response)
      throw new Error(errorMsg)
    }
  } catch (error) {
    console.error('加载绘本详情失败:', error)

    // 隐藏加载提示
    uni.hideLoading()

    // 设置错误状态
    loadError.value = true
    const errorMsg = error instanceof Error ? error.message : '未知错误'
    errorMessage.value = errorMsg

    // 显示错误提示
    uni.showToast({
      title: `加载失败: ${errorMsg}`,
      icon: 'none',
      duration: 3000
    })
  } finally {
    loading.value = false
    imageLoading.value = false
  }
}

// 重试加载绘本详情
function retryLoadBookDetail() {
  if (bookId.value) {
    loadBookDetail(bookId.value)
  }
}

async function loadAudioResources(bookId: string, retryCount = 0) {
  const maxRetries = 2
  const retryDelay = 1000 * (retryCount + 1)
  const cacheKey = `audio_${bookId}`

  try {
    audioLoading.value = true

    // 检查缓存
    if (audioCache.has(cacheKey)) {
      audioResources.value = audioCache.get(cacheKey) || []
      console.log(`音频资源从缓存加载: 共${audioResources.value.length}个音频`)
      return
    }

    const response = await getBookAudio(Number(bookId))

    if (response && response.code === 0) {
      audioResources.value = response.data || []

      // 缓存音频资源
      audioCache.set(cacheKey, audioResources.value)


    } else {
      throw new Error(response?.msg || '音频资源加载失败')
    }
  } catch (error) {
    console.error(`加载音频资源失败 (尝试${retryCount + 1}/${maxRetries + 1}):`, error)

    // 重试逻辑
    if (retryCount < maxRetries) {
      console.log(`${retryDelay / 1000}秒后重试加载音频资源...`)
      setTimeout(() => {
        loadAudioResources(bookId, retryCount + 1)
      }, retryDelay)
    } else {
      // 最终失败，使用空数组
      audioResources.value = []
      uni.showToast({
        title: '音频加载失败，将使用静音模式',
        icon: 'none',
        duration: 2000
      })
    }
  } finally {
    audioLoading.value = false
  }
}

// 加载绘本集信息
async function loadBookSetInfo() {
  try {
    console.log('开始加载绘本集信息, bookDetail:', bookDetail.value)

    if (!bookDetail.value?.bookSetId) {
      console.log('当前绘本不属于任何绘本集，跳过绘本集信息加载')
      return
    }

    console.log('准备调用 getBookSetDetail, bookSetId:', bookDetail.value.bookSetId)
    const response = await getBookSetDetail(bookDetail.value.bookSetId)

    console.log('getBookSetDetail 响应:', response)

    if (response && response.code === 0) {
      bookSetDetail.value = response.data
      bookSetBooks.value = response.data.books || []

      // 找到当前绘本在绘本集中的位置
      currentBookIndex.value = bookSetBooks.value.findIndex(book => book.id === Number(bookId.value))


    } else {
      console.warn('绘本集详情API响应异常:', response)
    }
  } catch (error) {
    console.error('加载绘本集信息失败:', error)
    // 失败时重置相关状态
    bookSetDetail.value = null
    bookSetBooks.value = []
    currentBookIndex.value = -1
  }
}

// 检查收藏状态
async function checkFavoriteStatus() {
  try {
    if (!bookId.value) return

    const response = await checkBookFavoriteStatus(Number(bookId.value), 'book')
    if (response && response.code === 0) {
      isFavorite.value = response.data || false
      console.log('收藏状态检查完成:', isFavorite.value ? '已收藏' : '未收藏')
    }
  } catch (error) {
    console.error('检查收藏状态失败:', error)
    // 失败时默认为未收藏
    isFavorite.value = false
  }
}

async function loadUserRecordings(pageId: number) {
  try {
    const response = await getUserRecordings({ pageNo: 1, pageSize: 10 })
    if (response && response.data && response.data.code === 0) {
      userRecordings.value = response.data.data.list || []
      console.log(`用户配音加载成功: 共${userRecordings.value.length}个配音`)
    } else {
      console.warn('用户配音加载失败:', response?.data?.msg || '未知错误')
      userRecordings.value = []
    }
  } catch (error) {
    console.error('加载用户配音失败:', error)
    userRecordings.value = []
  }
}

// 加载当前页面的用户录音
async function loadCurrentPageUserRecording() {
  try {
    const currentPageData = bookPages.value[currentPage.value]
    if (!currentPageData || !currentPageData.id) {
      console.log('当前页面数据不存在，无法加载用户录音')
      serverUserRecording.value = null
      return
    }

    console.log('🎵 加载当前页面用户录音，页面ID:', currentPageData.id)
    const response = await getUserRecordingByPage(currentPageData.id)

    if (response && response.code === 0 && response.data) {
      serverUserRecording.value = {
        id: response.data.id,
        audioUrl: response.data.audioUrl,
        duration: response.data.duration,
        recordingQuality: response.data.recordingQuality
      }
      console.log('✅ 用户录音加载成功:', serverUserRecording.value)
    } else {
      console.log('📭 当前页面没有用户录音')
      serverUserRecording.value = null
    }
  } catch (error) {
    console.error('❌ 加载用户录音失败:', error)
    serverUserRecording.value = null
  }
}

// 更新本地阅读进度（不调用API）
function updateLocalReadingProgress() {
  if (!bookId.value) return

  // 计算当前页面的阅读时长（增量）
  const now = Date.now()
  const pageReadingTime = Math.floor((now - pageStartTime.value) / 1000) // 当前页面阅读时长（秒）

  // 累积总阅读时长
  totalReadingTime.value += pageReadingTime

  // 更新页面开始时间
  pageStartTime.value = now

  console.log('📖 本地阅读进度更新 - 页面:', currentPage.value + 1, '本页时长:', pageReadingTime, '秒，累计总时长:', totalReadingTime.value, '秒')
}

// 保存最终阅读记录到服务器（仅在退出时调用）
async function saveFinalReadingRecord(retryCount = 0) {
  const maxRetries = 3

  try {
    if (!bookId.value) return

    // 防止重复调用
    if (isSavingFinalRecord.value) {
      console.log('正在保存最终阅读记录，跳过重复调用')
      return
    }

    // 设置保存标志位
    isSavingFinalRecord.value = true

    // 如果是重新阅读模式，不保存阅读记录（避免更改已读状态）
    if (isRereading.value) {
      console.log('🔄 重新阅读模式，跳过保存阅读记录')
      return
    }

    // 计算最后一页的阅读时长
    const now = Date.now()
    const lastPageReadingTime = Math.floor((now - pageStartTime.value) / 1000)
    const finalTotalTime = totalReadingTime.value + lastPageReadingTime

    // 计算阅读进度，确保不为null或NaN
    let readingProgress = 0
    if (totalPages.value > 0) {
      readingProgress = (currentPage.value + 1) / totalPages.value
      // 确保进度在0-1之间，并且不是NaN
      readingProgress = Math.max(0, Math.min(1, readingProgress))
      if (isNaN(readingProgress)) {
        readingProgress = 0
      }
      console.log('📊 阅读进度计算: 当前页', currentPage.value + 1, '/ 总页数', totalPages.value, '= 进度', readingProgress)
    } else {
      console.warn('⚠️ 总页数为0，无法计算阅读进度')
      readingProgress = 0
    }

    const readingData: ReadingRecordCreateReqVO = {
      bookId: Number(bookId.value),
      planId: planId.value ? Number(planId.value) : undefined, // 添加计划ID
      lastPage: currentPage.value + 1,
      readingProgress: Number(readingProgress) || 0, // 确保是数字且不为null
      readingTime: finalTotalTime, // 传递总阅读时长
      readingMode: readingMode.value,
      isCompleted: totalPages.value > 0 && currentPage.value >= totalPages.value - 1
    }

    console.log('💾 保存最终阅读记录到服务器:', readingData)
    console.log('📋 计划相关信息:', {
      planId: planId.value,
      taskId: taskId.value,
      isCompleted: readingData.isCompleted,
      hasPlannId: !!readingData.planId
    })

    // 验证数据完整性
    const validatedData = validateReadingRecord(readingData)
    const response = await saveReadingRecord(validatedData)
    if (response && response.code === 0) {
      console.log('✅ 最终阅读记录保存成功！总阅读时长:', finalTotalTime, '秒，最后页面:', currentPage.value + 1)

      // 如果有计划ID且绘本已完成，记录任务状态同步信息
      if (readingData.planId && readingData.isCompleted) {
        console.log('🎯 绘本已完成且有计划ID，后端应该会自动同步任务状态')

        // 触发计划变更事件，通知首页和计划详情页面刷新数据
        uni.$emit('planChanged')
        console.log('📢 已触发planChanged事件，通知相关页面刷新计划数据')
      }

      // 如果来自作业且绘本已完成，提交作业完成记录（仅限阅读作业，且非老师）
      if (fromAssignment.value && assignmentId.value && readingData.isCompleted && requirementType.value === 'read' && !isTeacher.value) {
        await submitAssignmentCompletion()
      }

      // 成功后尝试同步离线记录
      await syncOfflineRecords()
    } else {
      throw new Error(response?.msg || '保存失败')
    }
  } catch (error) {
    console.error(`保存最终阅读记录失败 (尝试${retryCount + 1}/${maxRetries + 1}):`, error)

    // 重试逻辑
    if (retryCount < maxRetries) {
      const retryDelay = 1000 * Math.pow(2, retryCount) // 指数退避
      setTimeout(() => {
        // 重试时重置标志位，允许重试执行
        isSavingFinalRecord.value = false
        saveFinalReadingRecord(retryCount + 1)
      }, retryDelay)
    } else {
      // 最终失败，保存到离线队列
      const now = Date.now()
      const lastPageReadingTime = Math.floor((now - pageStartTime.value) / 1000)
      const finalTotalTime = totalReadingTime.value + lastPageReadingTime

      // 计算阅读进度，确保不为null或NaN
      let readingProgress = 0
      if (totalPages.value > 0) {
        readingProgress = (currentPage.value + 1) / totalPages.value
        readingProgress = Math.max(0, Math.min(1, readingProgress))
        if (isNaN(readingProgress)) {
          readingProgress = 0
        }
      }

      const readingData: ReadingRecordCreateReqVO = {
        bookId: Number(bookId.value),
        planId: planId.value ? Number(planId.value) : undefined, // 添加计划ID
        lastPage: currentPage.value + 1,
        readingProgress: Number(readingProgress) || 0, // 确保是数字且不为null
        readingTime: finalTotalTime,
        readingMode: readingMode.value,
        isCompleted: totalPages.value > 0 && currentPage.value >= totalPages.value - 1
      }

      // 验证数据完整性后添加到离线队列
      const validatedData = validateReadingRecord(readingData)
      offlineReadingRecords.value.push(validatedData)
      saveOfflineRecords()

      console.log('最终阅读记录已保存到离线队列，将在网络恢复后同步')
    }
  } finally {
    // 无论成功还是失败，都重置标志位（除非是重试）
    if (retryCount === 0) {
      isSavingFinalRecord.value = false
    }
  }
}

// 保存初始阅读记录（用户刚进入绘本时）
async function saveInitialReadingRecord() {
  try {
    if (!bookId.value) return

    // 初始化阅读时间跟踪
    const now = Date.now()
    readingStartTime.value = now
    pageStartTime.value = now
    totalReadingTime.value = 0

    // 优化：检查是否已有阅读记录，避免不必要的API调用
    try {
      const existingRecord = await getReadingRecord(Number(bookId.value))
      if (existingRecord && existingRecord.code === 0 && existingRecord.data) {
        console.log('绘本已有阅读记录，跳过初始记录保存，避免覆盖已完成状态')
        return
      }
    } catch (error) {
      // 如果获取记录失败，继续保存初始记录
      console.log('获取现有阅读记录失败，继续保存初始记录:', error)
    }

    const readingData: ReadingRecordCreateReqVO = {
      bookId: Number(bookId.value),
      planId: planId.value ? Number(planId.value) : undefined, // 添加计划ID
      lastPage: 1, // 初始页面为第1页
      readingProgress: Number(0) || 0, // 初始进度为0，确保是数字
      readingTime: 0, // 初始阅读时长为0
      readingMode: readingMode.value,
      isCompleted: false // 刚开始阅读，未完成
    }

    // 验证数据完整性
    const validatedData = validateReadingRecord(readingData)
    const response = await saveReadingRecord(validatedData)
    if (response && response.code === 0) {
      console.log('初始阅读记录保存成功，绘本已添加到最近阅读')
    } else {
      console.warn('初始阅读记录保存失败:', response?.msg || '未知错误')
    }
  } catch (error) {
    console.error('保存初始阅读记录失败:', error)
  }
}

// 提交作业完成记录
async function submitAssignmentCompletion() {
  try {
    if (!assignmentId.value || !bookId.value || !requirementType.value) {
      console.log('作业参数不完整，跳过提交作业完成记录')
      return
    }

    // 如果是老师，不提交作业完成记录
    if (isTeacher.value) {
      console.log('老师模式，跳过提交作业完成记录')
      return
    }

    const completionData = {
      bookId: Number(bookId.value),
      completionType: requirementType.value,
      recordingUrl: requirementType.value === 'audio' && serverUserRecording.value?.audioUrl
        ? serverUserRecording.value.audioUrl
        : undefined
    }

    console.log('📝 提交作业完成记录:', {
      assignmentId: assignmentId.value,
      ...completionData
    })

    const response = await completeAssignment(Number(assignmentId.value), completionData)
    if (response && response.code === 0) {
      console.log('✅ 作业完成记录提交成功')
      const completionMessage = requirementType.value === 'audio' ? '配音作业已完成' : '阅读作业已完成'
      uni.showToast({
        title: completionMessage,
        icon: 'success',
        duration: 2000
      })
    } else {
      console.warn('⚠️ 作业完成记录提交失败:', response?.msg)
    }
  } catch (error) {
    console.error('❌ 提交作业完成记录失败:', error)
    // 不显示错误提示，避免影响用户体验
  }
}

// 显示作业状态提示
function showAssignmentStatusHint() {
  if (!fromAssignment.value || !requirementType.value) {
    return
  }

  let hintMessage = ''

  if (isTeacher.value) {
    // 老师的提示信息
    hintMessage = requirementType.value === 'audio'
      ? '您正在预览配音作业绘本，您的操作不会影响作业完成状态'
      : '您正在预览阅读作业绘本，您的操作不会影响作业完成状态'
  } else {
    // 学生的提示信息
    hintMessage = requirementType.value === 'audio'
      ? '这是配音作业，请为绘本的所有页面录制配音来完成作业'
      : '这是阅读作业，阅读完整本绘本即可完成作业'
  }

  uni.showToast({
    title: hintMessage,
    icon: 'none',
    duration: 3000
  })
}

// 检查并提交配音作业完成记录
async function checkAndSubmitAudioAssignmentCompletion() {
  try {
    if (!fromAssignment.value || !assignmentId.value || requirementType.value !== 'audio') {
      return
    }

    // 检查是否所有页面都有录音
    const allPagesRecorded = await checkAllPagesRecorded()

    if (allPagesRecorded) {
      console.log('🎤 所有页面录音完成，提交配音作业完成记录')
      await submitAssignmentCompletion()
    } else {
      const recordedCount = await getRecordedPagesCount()
      const totalPages = bookPages.value.length
      console.log(`🎤 配音进度: ${recordedCount}/${totalPages} 页面已录音`)

      uni.showToast({
        title: `已录音 ${recordedCount}/${totalPages} 页`,
        icon: 'none',
        duration: 2000
      })
    }
  } catch (error) {
    console.error('❌ 检查配音作业完成状态失败:', error)
  }
}

// 检查所有页面是否都已录音
async function checkAllPagesRecorded() {
  try {
    if (!bookPages.value || bookPages.value.length === 0) {
      return false
    }

    // 检查每个页面是否都有录音（本地或服务器）
    for (const page of bookPages.value) {
      const hasLocalRecording = userRecordings.value.some(recording => recording.pageId === page.id)

      if (!hasLocalRecording) {
        // 检查服务器是否有录音
        try {
          const response = await getUserRecordingByPage(page.id)
          if (!response || response.code !== 0 || !response.data) {
            return false // 该页面没有录音
          }
        } catch (error) {
          return false // 检查失败，认为没有录音
        }
      }
    }

    return true // 所有页面都有录音
  } catch (error) {
    console.error('❌ 检查页面录音状态失败:', error)
    return false
  }
}

// 获取已录音页面数量
async function getRecordedPagesCount() {
  try {
    if (!bookPages.value || bookPages.value.length === 0) {
      return 0
    }

    let recordedCount = 0

    for (const page of bookPages.value) {
      const hasLocalRecording = userRecordings.value.some(recording => recording.pageId === page.id)

      if (hasLocalRecording) {
        recordedCount++
      } else {
        // 检查服务器是否有录音
        try {
          const response = await getUserRecordingByPage(page.id)
          if (response && response.code === 0 && response.data) {
            recordedCount++
          }
        } catch (error) {
          // 检查失败，不计入已录音
        }
      }
    }

    return recordedCount
  } catch (error) {
    console.error('❌ 获取已录音页面数量失败:', error)
    return 0
  }
}

onLoad((options: any) => {
  // 检查用户登录状态
  const userStore = useUserStore()
  if (!userStore.isLoggedIn) {
    console.log('用户未登录，跳转到登录页面')
    const currentUrl = '/pages-sub/reading/picture-book-reader/index' +
      (options.bookId ? `?bookId=${options.bookId}` : '') +
      (options.title ? `&title=${options.title}` : '') +
      (options.planId ? `&planId=${options.planId}` : '') +
      (options.taskId ? `&taskId=${options.taskId}` : '')

    uni.reLaunch({
      url: '/pages/login/index?redirect=' + encodeURIComponent(currentUrl)
    })
    return
  }

  // 获取页面参数
  bookId.value = options.bookId || ''
  bookTitle.value = decodeURIComponent(options.title || '绘本阅读')
  planId.value = options.planId || '' // 接收计划ID
  taskId.value = options.taskId || '' // 接收任务ID

  // 接收作业相关参数
  assignmentId.value = options.assignmentId || ''
  requirementType.value = options.requirementType || ''
  fromAssignment.value = options.fromAssignment === 'true'
  isTeacher.value = options.isTeacher === 'true'

  console.log('阅读器页面参数:', {
    bookId: bookId.value,
    planId: planId.value,
    taskId: taskId.value,
    assignmentId: assignmentId.value,
    requirementType: requirementType.value,
    fromAssignment: fromAssignment.value
  })

  // 重置重新阅读标记
  isRereading.value = false

  // 根据书籍标题判断是否为英文书籍
  isEnglishBook.value = /[a-zA-Z]/.test(bookTitle.value)

  // 加载绘本详情
  if (bookId.value) {
    loadBookDetail(bookId.value)
    // 立即保存阅读记录，标记用户开始阅读这本绘本
    saveInitialReadingRecord()
  }
})

onMounted(async () => {
  console.log('📖 绘本阅读器组件已挂载')
  console.log('🔍 组件挂载时覆盖层计数器:', overlayCounter.value)

  // 重置防重复保存标志位
  isSavingFinalRecord.value = false

  // 获取系统信息
  const systemInfo = uni.getSystemInfoSync()
  statusBarHeight.value = systemInfo.statusBarHeight || 0

  // 初始化设备方向状态
  if (systemInfo.windowWidth && systemInfo.windowHeight) {
    const currentDeviceOrientation = systemInfo.windowWidth > systemInfo.windowHeight ? 'landscape' : 'portrait'
    deviceOrientation.value = currentDeviceOrientation
    console.log('📱 初始设备方向:', currentDeviceOrientation === 'landscape' ? '横屏' : '竖屏',
                `(${systemInfo.windowWidth}x${systemInfo.windowHeight})`)
  }

  // 清理本地存储中的无效数据
  cleanupLocalStorage()

  // 加载离线记录
  loadOfflineRecords()

  // 加载翻译缓存
  loadTranslationCache()

  // 初始化录音管理器
  initRecorderManager()

  // 初始化录音权限检查
  await initRecordingPermission()

  // 录音存储管理功能已删除

  // 获取设备性能信息（简化版）
  try {
    await getDevicePerformance()
  } catch (error) {
    console.log('获取设备性能信息失败，使用默认值:', error)
  }

  // 启动性能监控（如果启用）
  if (performanceConfig.monitoringEnabled) {
    startPerformanceMonitoring()
  }

  // 重置用户手动暂停标记（新的阅读会话开始）
  userManuallyStopped = false
  console.log('🔄 新的阅读会话开始，重置用户手动暂停标记')

  // 加载阅读设置
  loadReadingSettings()

  // 默认设置为横屏模式
  try {
    // 注意：某些平台可能不支持程序化设置屏幕方向
    // uni.setScreenOrientation({
    //   orientation: 'landscape'
    // })
  } catch (error) {
    console.log('设置横屏失败:', error)
  }

  // 监听屏幕方向变化
  uni.onWindowResize((res) => {
    // 根据窗口尺寸判断当前设备方向
    if (res && res.size) {
      const { windowWidth, windowHeight } = res.size
      const currentDeviceOrientation = windowWidth > windowHeight ? 'landscape' : 'portrait'

      // 如果检测到的方向与当前状态不一致，自动同步
      if (currentDeviceOrientation !== deviceOrientation.value) {
        console.log('📱 检测到设备方向变化:', currentDeviceOrientation === 'landscape' ? '横屏' : '竖屏')
        deviceOrientation.value = currentDeviceOrientation
      }
    }
  })

  // 3秒后自动隐藏提示
  setTimeout(() => {
    showTip.value = false
  }, 3000)

  // 尝试同步离线记录
  syncOfflineRecords()

  // 启动控制栏自动隐藏定时器
  startControlsAutoHideTimer()

  console.log('📖 页面加载完成')
})

// 停止性能监控
function stopPerformanceMonitoring() {
  if (performanceMonitorTimer.value) {
    clearInterval(performanceMonitorTimer.value)
    performanceMonitorTimer.value = null
  }

  if (batteryMonitorTimer.value) {
    clearInterval(batteryMonitorTimer.value)
    batteryMonitorTimer.value = null
  }

  console.log('📊 性能监控已停止')
}

onUnmounted(() => {
  console.log('📖 绘本阅读器组件即将卸载')
  console.log('🔍 组件卸载时覆盖层计数器:', overlayCounter.value)
})

onShow(() => {
  // 页面显示时重新加载设置（从设置页面返回时）
  console.log('📱 阅读器页面显示，重新加载设置')
  console.log('🔍 当前状态:', {
    userManuallyStopped: userManuallyStopped,
    currentPage: currentPage.value + 1,
    totalPages: totalPages.value,
    isAudioPlaying: isAudioPlaying.value,
    autoTurnPage: readingSettings.value.autoTurnPage,
    autoPlayAudio: readingSettings.value.autoPlayAudio,
    autoReadNext: readingSettings.value.autoReadNext
  })

  // 重新加载设置，传入true表示这是重新加载
  loadReadingSettings(true)
})

onHide(() => {
  console.log('📱 页面隐藏事件触发')

  // 立即停止音频播放并暂停自动播放
  stopAudioPlayback('页面隐藏', true) // 标记为用户操作，暂停自动播放

  // 清理所有定时器
  if (autoTurnTimer) {
    clearTimeout(autoTurnTimer)
    autoTurnTimer = null
  }

  // 页面隐藏时保存最终阅读记录（处理系统返回手势等情况）
  if (bookId.value && pageStartTime.value > 0) {
    console.log('页面隐藏，保存最终阅读记录')
    saveFinalReadingRecord()
  }
})

onUnmounted(() => {
  console.log('🗑️ 组件卸载，清理所有资源')

  // 停止音频播放并暂停自动播放
  stopAudioPlayback('组件卸载', true) // 标记为用户操作，暂停自动播放

  // 停止性能监控
  stopPerformanceMonitoring()

  // 保存最终的阅读记录（备用保障）
  if (bookId.value && pageStartTime.value > 0) {
    // 直接调用最终保存函数
    saveFinalReadingRecord()
  }

  // 清理所有定时器
  if (autoTurnTimer) {
    clearTimeout(autoTurnTimer)
    autoTurnTimer = null
  }
  if (audioTimer) {
    clearTimeout(audioTimer)
    audioTimer = null
  }
  if (nextBookTimer.value) {
    clearInterval(nextBookTimer.value)
    nextBookTimer.value = null
  }

  // 清理控制栏自动隐藏定时器
  clearControlsAutoHideTimer()

  // 清理用户操作定时器
  clearUserOperationTimer()

  isAudioActive = false

  // 退出时恢复竖屏
  if (isLandscape.value) {
    try {
      // uni.setScreenOrientation({
      //   orientation: 'portrait'
      // })
    } catch (error) {
      console.log('恢复屏幕方向失败:', error)
    }
  }
})



// 加载阅读设置
async function loadReadingSettings(isReload = false) {
  try {
    // 保存旧设置用于比较（仅在重新加载时）
    const oldSettings = isReload ? { ...readingSettings.value } : null

    console.log(isReload ? '🔄 重新加载用户设置' : '📥 初始加载用户设置')

    // 首先尝试从服务器加载用户设置
    await loadUserSettings()

    // 然后加载本地设置作为补充
    const savedSettings = uni.getStorageSync('readingSettings')
    if (savedSettings) {
      // 合并本地设置，但优先使用服务器设置
      readingSettings.value = { ...savedSettings, ...readingSettings.value }
    }

    // 应用设置
    readingMode.value = readingSettings.value.readingMode

    // 如果是重新加载，比较设置变化并智能应用
    if (isReload && oldSettings) {
      console.log('🔍 检查设置变化:', {
        autoPlayAudio: { old: oldSettings.autoPlayAudio, new: readingSettings.value.autoPlayAudio },
        autoTurnPage: { old: oldSettings.autoTurnPage, new: readingSettings.value.autoTurnPage },
        autoReadNext: { old: oldSettings.autoReadNext, new: readingSettings.value.autoReadNext },
        readingMode: { old: oldSettings.readingMode, new: readingSettings.value.readingMode }
      })

      // 处理自动播放音频设置变化
      if (oldSettings.autoPlayAudio !== readingSettings.value.autoPlayAudio) {
        if (readingSettings.value.autoPlayAudio && !userManuallyStopped && !isAudioPlaying.value) {
          console.log('🎵 自动播放音频已开启，启动音频播放')
          setTimeout(() => {
            startAutoAudio()
          }, 500)
        } else if (!readingSettings.value.autoPlayAudio && isAudioPlaying.value) {
          console.log('🔇 自动播放音频已关闭，停止当前音频')
          stopAudioPlayback('设置变化')
        }
      }

      // 处理自动翻页设置变化
      if (oldSettings.autoTurnPage !== readingSettings.value.autoTurnPage) {
        if (readingSettings.value.autoTurnPage) {
          console.log('⏰ 自动翻页已开启，启动自动翻页')
          startAutoTurnPage()
        } else {
          console.log('⏰ 自动翻页已关闭，停止自动翻页')
          if (autoTurnTimer) {
            clearTimeout(autoTurnTimer)
            autoTurnTimer = null
          }
        }
      }
    } else {
      // 初始加载时的逻辑
      // 如果开启了自动播放音频，但用户没有手动暂停
      if (readingSettings.value.autoPlayAudio && !userManuallyStopped) {
        console.log('🎵 自动播放音频已开启且用户未手动暂停，延迟开始播放')
        // 延迟一下开始播放音频
        setTimeout(() => {
          startAutoAudio()
        }, 1000)
      } else if (userManuallyStopped) {
        console.log('🔇 用户已手动暂停音频，跳过自动播放')
      }

      // 如果开启了自动翻页
      if (readingSettings.value.autoTurnPage) {
        startAutoTurnPage()
      }
    }

    // 加载音频来源设置
    const savedAudioSource = uni.getStorageSync('audioSource')
    if (savedAudioSource) {
      audioSource.value = savedAudioSource
      console.log('📼 已恢复音频来源设置:', audioSource.value)
    }

    // 加载录音质量设置
    const savedRecordingQuality = uni.getStorageSync('recordingQuality')
    if (savedRecordingQuality && recordingConfig[savedRecordingQuality as keyof typeof recordingConfig]) {
      recordingQuality.value = savedRecordingQuality as 'low' | 'medium' | 'high'
      console.log('📼 已恢复录音质量设置:', recordingQuality.value)
    }

    // 显示最终的设置状态
    console.log('✅ 设置加载完成，当前配置:', {
      readingMode: readingSettings.value.readingMode,
      autoPlayAudio: readingSettings.value.autoPlayAudio,
      autoTurnPage: readingSettings.value.autoTurnPage,
      autoTurnPageInterval: readingSettings.value.autoTurnPageInterval,
      autoTurnAfterAudio: readingSettings.value.autoTurnAfterAudio,
      autoReadNext: readingSettings.value.autoReadNext,
      audioSource: audioSource.value,
      recordingQuality: recordingQuality.value
    })
  } catch (error) {
    console.log('加载设置失败:', error)
  }
}

// 从服务器加载用户设置
async function loadUserSettings() {
  try {
    const response = await getUserSettings()

    console.log('🔧 阅读器加载用户设置:', response)

    if (response && response.code === 0) {
      const userSettings = response.data

      // 映射服务器设置到阅读器设置
      readingSettings.value = {
        ...readingSettings.value,
        readingMode: userSettings.readingMode || readingSettings.value.readingMode,
        autoPlayAudio: userSettings.autoPlayAudio !== undefined ? userSettings.autoPlayAudio : readingSettings.value.autoPlayAudio,
        autoTurnPage: userSettings.autoTurnPage !== undefined ? userSettings.autoTurnPage : readingSettings.value.autoTurnPage,
        autoTurnPageInterval: userSettings.turnPageDelay || readingSettings.value.autoTurnPageInterval,
        autoTurnAfterAudio: userSettings.autoTurnAfterAudio !== undefined ? userSettings.autoTurnAfterAudio : readingSettings.value.autoTurnAfterAudio,
        autoReadNext: userSettings.autoReadNext !== undefined ? userSettings.autoReadNext : readingSettings.value.autoReadNext,
      }

      console.log('✅ 用户设置加载成功:', readingSettings.value)
    }
  } catch (error) {
    console.log('⚠️ 从服务器加载用户设置失败，使用默认设置:', error)
  }
}

// 保存设置到服务器
async function saveSettingsToServer() {
  try {
    const updateData = {
      readingMode: readingSettings.value.readingMode,
      autoPlayAudio: readingSettings.value.autoPlayAudio,
      autoTurnPage: readingSettings.value.autoTurnPage,
      turnPageDelay: readingSettings.value.autoTurnPageInterval,
      autoTurnAfterAudio: readingSettings.value.autoTurnAfterAudio,
      autoReadNext: readingSettings.value.autoReadNext,
    }

    console.log('🔧 阅读器保存设置到服务器:', updateData)

    const response = await updateUserSettings(updateData)

    if (response && response.code === 0) {
      console.log('✅ 阅读器设置保存成功')
    } else {
      console.log('⚠️ 阅读器设置保存失败:', response?.msg)
    }
  } catch (error) {
    console.log('⚠️ 阅读器设置保存到服务器失败:', error)
  }
}

// 开始自动音频播放
function startAutoAudio() {
  console.log('🔍 startAutoAudio 被调用，userManuallyStopped:', userManuallyStopped)
  // 检查用户是否手动暂停了音频
  if (userManuallyStopped) {
    console.log('🔇 用户已手动暂停音频，跳过自动播放')
    return
  }
  console.log('✅ 用户未手动暂停，继续自动播放流程')

  if (!isAudioPlaying.value) {
    // 获取当前页面数据
    const currentPageData = bookPages.value[currentPage.value]
    if (!currentPageData) {
      console.log('当前页面数据不存在')
      return
    }

    // 根据音频来源选择播放的音频
    let audioUrl = ''
    let currentAudioDuration = 0

    if (audioSource.value === 'official') {
      // 使用官方音频
      audioUrl = currentPageData.officialAudioUrl || ''
      currentAudioDuration = currentPageData.audioDuration || 0

      console.log('🎵 检查官方音频:', {
        pageNumber: currentPageData.pageNumber,
        officialAudioUrl: currentPageData.officialAudioUrl,
        audioDuration: currentPageData.audioDuration,
        audioUrl: audioUrl
      })

      if (!audioUrl) {
        console.log('❌ 当前页面暂无官方音频')
        uni.showToast({
          title: '当前页面暂无官方音频',
          icon: 'none'
        })
        return
      }
    } else {
      // 用户录制音频
      const userRecording = getCurrentPageUserRecording()

      if (!userRecording) {
        // 如果没有用户录制音频，回退到官方音频
        audioUrl = currentPageData.officialAudioUrl || ''
        currentAudioDuration = currentPageData.audioDuration || 0

        if (!audioUrl) {
          console.log('当前页面既无用户录制音频也无官方音频')
          uni.showToast({
            title: '当前页面暂无音频资源',
            icon: 'none'
          })
          return
        }

        console.log('⚠️ 暂无用户录制音频，回退到官方音频')
        uni.showToast({
          title: '暂无用户录制音频，将播放官方音频',
          icon: 'none'
        })
      } else {
        // 使用用户录制的音频
        audioUrl = userRecording.filePath
        currentAudioDuration = userRecording.duration || 0

        console.log('🎵 使用用户录制音频:', {
          id: userRecording.id,
          filePath: userRecording.filePath,
          duration: userRecording.duration,
          quality: userRecording.quality
        })

        // 更新播放次数
        updateRecordingPlayCount(userRecording.id)
      }
    }

    if (!audioUrl) {
      console.log('音频地址无效')
      return
    }

    const sourceText = audioSource.value === 'official' ? '官方音频' : '用户录制音频'
    console.log(`开始播放${sourceText}: ${audioUrl}`)

    // 清除之前的音频定时器
    if (audioTimer) {
      clearTimeout(audioTimer)
    }

    // 先停止之前的音频播放
    stopAudioPlayback('开始播放新音频')

    // 创建音频上下文
    currentAudioContext = uni.createInnerAudioContext()
    currentAudioContext.src = audioUrl

    // 重置音频进度
    audioProgress.value = 0
    audioCurrentTime.value = 0
    audioDuration.value = currentAudioDuration

    currentAudioContext.onPlay(() => {
      console.log('🎵 音频真正开始播放，设置播放状态')
      // 在音频真正开始播放时设置状态
      isAudioPlaying.value = true
      isAudioActive = true

      // 注意：不在这里清除用户手动暂停标记，只有用户主动点击播放按钮时才清除

      startAudioProgressTimer()
    })

    currentAudioContext.onTimeUpdate(() => {
      // 更新播放进度
      audioCurrentTime.value = currentAudioContext.currentTime
      if (audioDuration.value > 0) {
        audioProgress.value = (audioCurrentTime.value / audioDuration.value) * 100
      }
    })

    currentAudioContext.onEnded(() => {
      console.log('音频播放结束')
      isAudioPlaying.value = false
      isAudioActive = false
      stopAudioProgressTimer()

      // 重置进度
      audioProgress.value = 100
      audioCurrentTime.value = audioDuration.value

      // 如果设置了音频播放完自动翻页
      if (readingSettings.value.autoTurnAfterAudio) {
        console.log('🎵 音频播放完成，检查自动翻页设置', {
          currentPage: currentPage.value + 1,
          totalPages: totalPages.value,
          isLastPage: currentPage.value === totalPages.value - 1,
          autoReadNext: readingSettings.value.autoReadNext
        })

        setTimeout(() => {
          if (currentPage.value < totalPages.value - 1) {
            console.log('📖 音频播放完成，自动翻到下一页')
            nextPage()
          } else if (readingSettings.value.autoReadNext) {
            console.log('📚 音频播放完成，在最后一页且开启自动阅读下一本，准备跳转')
            // 自动阅读下一本，传入true表示这是自动触发的
            goToNextBook(true)
          } else {
            console.log('📚 音频播放完成，在最后一页但未开启自动阅读下一本')
          }
        }, 1000) // 延迟1秒翻页
      }
    })

    currentAudioContext.onError((error) => {
      console.error('音频播放错误:', error)
      isAudioPlaying.value = false
      isAudioActive = false
      stopAudioProgressTimer()
      uni.showToast({
        title: '音频播放失败',
        icon: 'none'
      })
    })

    // 立即设置播放状态，让用户看到按钮变化
    console.log('🎵 准备播放音频，立即设置播放状态为 true')
    isAudioPlaying.value = true
    isAudioActive = true

    currentAudioContext.play()
  }
}

// 开始音频进度计时器
function startAudioProgressTimer() {
  stopAudioProgressTimer() // 先停止之前的计时器

  audioProgressTimer.value = setInterval(() => {
    if (isAudioPlaying.value && audioDuration.value > 0) {
      audioCurrentTime.value += 0.1
      audioProgress.value = (audioCurrentTime.value / audioDuration.value) * 100

      // 防止超过100%
      if (audioProgress.value > 100) {
        audioProgress.value = 100
        audioCurrentTime.value = audioDuration.value
      }
    }
  }, 100) // 每100ms更新一次
}

// 停止音频进度计时器
function stopAudioProgressTimer() {
  if (audioProgressTimer.value) {
    clearInterval(audioProgressTimer.value)
    audioProgressTimer.value = null
  }
}

// 统一的音频停止函数
function stopAudioPlayback(reason = '未知原因', isUserAction = false) {
  console.log(`🔇 停止音频播放 - ${reason}`)

  // 如果是用户手动操作，设置手动暂停标记
  if (isUserAction) {
    console.log('🔍 用户手动操作，设置暂停标记前 userManuallyStopped:', userManuallyStopped)
    userManuallyStopped = true
    console.log('🔇 设置用户手动暂停标记，新值:', userManuallyStopped)
    console.log('⏸️ 自动播放已暂停，用户重新进入页面时需要手动播放音频')
  } else {
    console.log('🔍 非用户手动操作，保持 userManuallyStopped:', userManuallyStopped)
  }

  // 停止音频播放状态
  isAudioPlaying.value = false
  isAudioActive = false
  console.log('🔇 设置音频播放状态为 false，按钮应显示播放图标')

  // 清理音频相关定时器
  if (audioTimer) {
    clearTimeout(audioTimer)
    audioTimer = null
  }

  // 清理音频播放防抖定时器
  if (audioPlayDebounceTimer) {
    clearTimeout(audioPlayDebounceTimer)
    audioPlayDebounceTimer = null
  }

  // 清理音频控制防抖定时器
  if (audioControlDebounceTimer) {
    clearTimeout(audioControlDebounceTimer)
    audioControlDebounceTimer = null
  }

  // 停止音频进度计时器
  stopAudioProgressTimer()

  // 重置音频进度
  audioProgress.value = 0
  audioCurrentTime.value = 0

  // 如果存在音频上下文，销毁它
  if (currentAudioContext) {
    try {
      currentAudioContext.destroy()
      currentAudioContext = null
    } catch (error) {
      console.log('销毁音频上下文失败:', error)
    }
  }

  console.log('✅ 音频播放已完全停止')
}

// 开始自动翻页
function startAutoTurnPage() {
  console.log('⏰ 启动自动翻页定时器', {
    currentPage: currentPage.value + 1,
    totalPages: totalPages.value,
    interval: readingSettings.value.autoTurnPageInterval,
    isAudioActive: isAudioActive,
    autoTurnAfterAudio: readingSettings.value.autoTurnAfterAudio,
    autoReadNext: readingSettings.value.autoReadNext
  })

  // 如果音频正在播放且设置了音频播放完自动翻页，则不启动延迟翻页
  if (isAudioActive && readingSettings.value.autoTurnAfterAudio) {
    console.log('音频播放中，延迟翻页暂停')
    return
  }

  if (autoTurnTimer) {
    clearTimeout(autoTurnTimer)
  }

  autoTurnTimer = setTimeout(() => {
    // 再次检查音频状态，确保音频播放完翻页优先
    if (isAudioActive && readingSettings.value.autoTurnAfterAudio) {
      console.log('音频播放中，取消延迟翻页')
      return
    }

    if (currentPage.value < totalPages.value - 1) {
      console.log('⏰ 自动翻页定时器触发，翻到下一页')
      nextPage()
      // 继续下一次自动翻页
      if (readingSettings.value.autoTurnPage) {
        startAutoTurnPage()
      }
    } else if (readingSettings.value.autoReadNext) {
      console.log('⏰ 自动翻页定时器触发，在最后一页且开启自动阅读下一本，准备跳转')
      // 自动阅读下一本，传入true表示这是自动触发的
      goToNextBook(true)
    } else {
      console.log('⏰ 自动翻页定时器触发，在最后一页但未开启自动阅读下一本')
    }
  }, readingSettings.value.autoTurnPageInterval * 1000)
}



// 跳转到下一本绘本
async function goToNextBook(isUserTriggered = false) {
  try {
    // 只有在非用户主动触发时才检查自动阅读下一本功能设置
    if (!isUserTriggered && !readingSettings.value.autoReadNext) {
      console.log('自动阅读下一本功能未开启')
      return
    }

    // 先保存当前绘本的阅读记录
    await saveFinalReadingRecord()

    // 检查是否有绘本集信息
    if (!bookSetDetail.value || bookSetBooks.value.length === 0) {
      uni.showToast({
        title: '当前绘本不属于绘本集',
        icon: 'none',
        duration: 2000
      })
      return
    }

    // 检查是否有下一本绘本
    const nextBookIndex = currentBookIndex.value + 1
    if (nextBookIndex >= bookSetBooks.value.length) {
      // 已经是最后一本，显示完成提示
      uni.showModal({
        title: '阅读完成',
        content: `恭喜完成整个绘本集《${bookSetDetail.value.title}》的阅读！`,
        showCancel: false,
        confirmText: '确定',
        success: () => {
          // 可以跳转到绘本集页面或首页
          uni.navigateBack()
        }
      })
      return
    }

    // 获取下一本绘本信息
    nextBook.value = bookSetBooks.value[nextBookIndex]

    // 显示倒计时对话框
    showNextBookCountdown()

  } catch (error) {
    console.error('准备跳转下一本绘本失败:', error)
    uni.showToast({
      title: '跳转失败，请重试',
      icon: 'none'
    })
  }
}

// 显示下一本绘本倒计时对话框
function showNextBookCountdown() {
  showNextBookDialog.value = true
  nextBookCountdown.value = 3

  // 开始倒计时
  nextBookTimer.value = setInterval(() => {
    nextBookCountdown.value--
    if (nextBookCountdown.value <= 0) {
      // 倒计时结束，自动跳转
      confirmAutoReadNext()
    }
  }, 1000)
}

// 取消自动阅读下一本
function cancelAutoReadNext() {
  // 清除倒计时
  if (nextBookTimer.value) {
    clearInterval(nextBookTimer.value)
    nextBookTimer.value = null
  }

  // 隐藏对话框
  showNextBookDialog.value = false
  nextBook.value = null

  // 弹窗关闭后，重新启动控制栏自动隐藏定时器
  if (showControls.value) {
    startControlsAutoHideTimer()
    console.log('📖 下一本绘本对话框取消，重新启动控制栏自动隐藏定时器')
  }

  console.log('用户取消自动阅读下一本')
}

// 确认自动阅读下一本
function confirmAutoReadNext() {
  // 清除倒计时
  if (nextBookTimer.value) {
    clearInterval(nextBookTimer.value)
    nextBookTimer.value = null
  }

  // 隐藏对话框
  showNextBookDialog.value = false

  // 弹窗关闭后，重新启动控制栏自动隐藏定时器
  if (showControls.value) {
    startControlsAutoHideTimer()
    console.log('📖 下一本绘本对话框确认，重新启动控制栏自动隐藏定时器')
  }

  if (nextBook.value) {
    // 跳转到下一本绘本
    jumpToNextBook(nextBook.value)
  }
}

// 实际跳转到下一本绘本
function jumpToNextBook(book: PictureBookRespVO) {
  try {
    console.log(`跳转到下一本绘本: ${book.title}`)

    // 构建跳转参数
    const params = {
      bookId: book.id.toString(),
      title: encodeURIComponent(book.title),
      // 如果有计划ID，继续传递
      ...(planId.value && { planId: planId.value }),
      ...(taskId.value && { taskId: taskId.value })
    }

    // 跳转到新的绘本阅读页面
    uni.redirectTo({
      url: `/pages-sub/reading/picture-book-reader/index?${Object.entries(params).map(([key, value]) => `${key}=${value}`).join('&')}`,
      success: () => {
        console.log('成功跳转到下一本绘本')
      },
      fail: (error) => {
        console.error('跳转到下一本绘本失败:', error)
        uni.showToast({
          title: '跳转失败',
          icon: 'none'
        })
      }
    })
  } catch (error) {
    console.error('跳转到下一本绘本出错:', error)
    uni.showToast({
      title: '跳转失败',
      icon: 'none'
    })
  }
}

// 页面切换
async function onPageChange(event: any) {
  const newPage = event.detail.current
  console.log(`📖 滑动翻页：${currentPage.value + 1} → ${newPage + 1}`)
  currentPage.value = newPage

  // 停止之前的音频和翻页定时器
  console.log('🔇 滑动翻页：停止当前页面的音频播放')
  stopAudioPlayback('滑动翻页')

  if (autoTurnTimer) {
    clearTimeout(autoTurnTimer)
    autoTurnTimer = null
  }

  // 隐藏翻译（页面切换时）
  if (showTranslation.value) {
    showTranslation.value = false
    translationText.value = ''
  }

  // 处理页面切换时的音频状态
  await handlePageChangeAudioState()

  // 更新本地阅读进度（翻页时不调用API）
  updateLocalReadingProgress()

  // 如果开启了自动播放音频，切换页面时播放新页面的音频
  console.log('🔍 滑动翻页检查自动播放条件:', {
    autoPlayAudio: readingSettings.value.autoPlayAudio,
    userManuallyStopped: userManuallyStopped,
    currentPage: currentPage.value
  })

  if (readingSettings.value.autoPlayAudio && !userManuallyStopped) {
    console.log('✅ 滑动翻页：满足自动播放条件，开始播放新页面音频')
    startAutoAudio()
  } else if (userManuallyStopped) {
    console.log('🔇 用户已手动暂停音频，跳过滑动翻页时的自动播放')
  } else if (!readingSettings.value.autoPlayAudio) {
    console.log('🔇 自动播放音频设置已关闭，跳过滑动翻页时的自动播放')
  }

  // 页面切换时重新开始自动翻页计时（如果没有音频播放或音频不自动翻页）
  if (readingSettings.value.autoTurnPage) {
    startAutoTurnPage()
  }
}

// 上一页
function prevPage() {
  if (currentPage.value > 0) {
    console.log(`📖 翻页：${currentPage.value + 1} → ${currentPage.value}`)

    // 重置控制栏自动隐藏定时器
    resetControlsAutoHideTimer()

    // 停止当前页面的音频播放
    stopAudioPlayback('翻页到上一页')

    // 清理翻页定时器
    if (autoTurnTimer) {
      clearTimeout(autoTurnTimer)
      autoTurnTimer = null
    }

    // 更新本地阅读进度
    updateLocalReadingProgress()

    currentPage.value--

    // 根据用户设置决定是否自动播放新页面的音频
    if (readingSettings.value.autoPlayAudio && !userManuallyStopped) {
      console.log('🎵 自动播放音频已开启，延迟播放新页面音频')
      // 清理之前的防抖定时器
      if (audioPlayDebounceTimer) {
        clearTimeout(audioPlayDebounceTimer)
      }
      // 延迟一小段时间确保翻页动画完成，并防止快速翻页时的音频冲突
      audioPlayDebounceTimer = setTimeout(() => {
        startAutoAudio()
      }, 300)
    } else if (userManuallyStopped) {
      console.log('🔇 用户已手动暂停音频，跳过自动播放')
    } else {
      console.log('🔇 自动播放音频已关闭，等待用户手动播放')
    }

    // 手动翻页时重新开始自动翻页计时
    if (readingSettings.value.autoTurnPage) {
      startAutoTurnPage()
    }
  }
}

// 下一页
function nextPage() {
  if (currentPage.value < totalPages.value - 1) {
    console.log(`📖 翻页：${currentPage.value + 1} → ${currentPage.value + 2}`)

    // 重置控制栏自动隐藏定时器
    resetControlsAutoHideTimer()

    // 停止当前页面的音频播放
    stopAudioPlayback('翻页到下一页')

    // 清理翻页定时器
    if (autoTurnTimer) {
      clearTimeout(autoTurnTimer)
      autoTurnTimer = null
    }

    // 更新本地阅读进度
    updateLocalReadingProgress()

    currentPage.value++

    // 根据用户设置决定是否自动播放新页面的音频
    if (readingSettings.value.autoPlayAudio && !userManuallyStopped) {
      console.log('🎵 自动播放音频已开启，延迟播放新页面音频')
      // 清理之前的防抖定时器
      if (audioPlayDebounceTimer) {
        clearTimeout(audioPlayDebounceTimer)
      }
      // 延迟一小段时间确保翻页动画完成，并防止快速翻页时的音频冲突
      audioPlayDebounceTimer = setTimeout(() => {
        startAutoAudio()
      }, 300)
    } else if (userManuallyStopped) {
      console.log('🔇 用户已手动暂停音频，跳过自动播放')
    } else {
      console.log('🔇 自动播放音频已关闭，等待用户手动播放')
    }

    // 手动翻页时重新开始自动翻页计时
    if (readingSettings.value.autoTurnPage) {
      startAutoTurnPage()
    }
  } else {
    // 已经是最后一页，不执行任何操作
    console.log('📚 已经是最后一页，无法继续翻页')
  }
}

// 处理在最后一页继续翻页的操作
function handleLastPageNextAction() {
  console.log('📚 用户在最后一页继续翻页，检查自动阅读下一本设置', {
    autoReadNext: readingSettings.value.autoReadNext
  })

  // 如果开启了自动阅读下一本，直接进入下一本流程
  if (readingSettings.value.autoReadNext) {
    console.log('✅ 自动阅读下一本已开启，直接进入下一本流程')
    goToNextBook(true) // 传入true表示用户主动触发
  } else {
    console.log('❌ 自动阅读下一本未开启，显示阅读完成选择对话框')
    // 显示阅读完成选择对话框
    showReadingCompleteDialog.value = true
  }
}

// 关闭阅读完成选择对话框
function closeReadingCompleteDialog() {
  showReadingCompleteDialog.value = false

  // 弹窗关闭后，重新启动控制栏自动隐藏定时器
  if (showControls.value) {
    startControlsAutoHideTimer()
    console.log('📖 阅读完成对话框关闭，重新启动控制栏自动隐藏定时器')
  }
}

// 选择阅读下一本
function chooseReadNext() {
  console.log('📖 用户选择阅读下一本')
  showReadingCompleteDialog.value = false

  // 弹窗关闭后，重新启动控制栏自动隐藏定时器
  if (showControls.value) {
    startControlsAutoHideTimer()
    console.log('📖 选择阅读下一本，重新启动控制栏自动隐藏定时器')
  }

  // 检查是否有下一本绘本
  if (!hasNextBook.value) {
    uni.showToast({
      title: '没有下一本绘本',
      icon: 'none',
      duration: 2000
    })
    return
  }

  // 启动用户主动阅读下一本流程
  goToNextBook(true)
}

// 选择重新阅读
function chooseReread() {
  console.log('🔄 用户选择重新阅读')
  showReadingCompleteDialog.value = false

  // 弹窗关闭后，重新启动控制栏自动隐藏定时器
  if (showControls.value) {
    startControlsAutoHideTimer()
    console.log('📖 选择重新阅读，重新启动控制栏自动隐藏定时器')
  }

  // 设置重新阅读标记
  isRereading.value = true

  // 重置到第一页
  currentPage.value = 0

  // 停止当前音频播放
  stopAudioPlayback('重新阅读')

  // 重置阅读时间跟踪（但不重置总时长，因为这是重新阅读）
  const now = Date.now()
  pageStartTime.value = now

  // 如果开启了自动播放音频，开始播放第一页音频
  if (readingSettings.value.autoPlayAudio && !userManuallyStopped) {
    setTimeout(() => {
      startAutoAudio()
    }, 500)
  }

  // 如果开启了自动翻页，重新开始自动翻页
  if (readingSettings.value.autoTurnPage) {
    startAutoTurnPage()
  }

  uni.showToast({
    title: '开始重新阅读',
    icon: 'success',
    duration: 1500
  })
}

// 选择退出阅读
function chooseExit() {
  console.log('🏠 用户选择退出阅读')
  showReadingCompleteDialog.value = false

  // 弹窗关闭后，重新启动控制栏自动隐藏定时器
  if (showControls.value) {
    startControlsAutoHideTimer()
    console.log('📖 选择退出阅读，重新启动控制栏自动隐藏定时器')
  }

  // 返回上一页
  goBack()
}

// 当前设备屏幕方向状态（用于按钮显示，不影响UI布局）
const deviceOrientation = ref<'portrait' | 'landscape'>('portrait')

// 图片显示方向状态（当不支持系统方向切换时使用）
const imageOrientation = ref<'portrait' | 'landscape'>('portrait')

// 当前图片的实际方向（基于图片长宽比）
const currentImageType = ref<'portrait' | 'landscape'>('portrait')

// 图片尺寸信息
const imageInfo = ref<{
  width: number
  height: number
  aspectRatio: number
}>({
  width: 0,
  height: 0,
  aspectRatio: 1
})

// 切换屏幕方向（只改变设备方向，不改变UI布局）
async function toggleOrientation() {
  // 重置控制栏自动隐藏定时器
  resetControlsAutoHideTimer()

  const targetOrientation = imageOrientation.value === 'portrait' ? 'landscape' : 'portrait'
  const orientationText = targetOrientation === 'landscape' ? '横屏' : '竖屏'

  console.log('🔄 尝试切换设备屏幕方向到:', orientationText)

  // 检查平台支持
  const uniAny = uni as any
  const isApiSupported = typeof uniAny.setScreenOrientation === 'function'

  if (!isApiSupported) {
    console.log('⚠️ 当前平台不支持程序化屏幕方向切换，使用图片方向切换')

    // 不支持系统API，直接切换图片方向
    imageOrientation.value = targetOrientation

    uni.showToast({
      title: `图片已切换到${orientationText}`,
      icon: 'success',
      duration: 1500
    })
    return
  }

  // 显示切换提示
  uni.showLoading({
    title: `切换到${orientationText}...`,
    mask: true
  })

  try {
    await new Promise<void>((resolve, reject) => {
      uniAny.setScreenOrientation({
        orientation: targetOrientation,
        success: () => {
          console.log('✅ 设备屏幕方向切换成功:', targetOrientation)
          deviceOrientation.value = targetOrientation
          imageOrientation.value = targetOrientation

          uni.hideLoading()
          uni.showToast({
            title: `已切换到${orientationText}`,
            icon: 'success',
            duration: 1500
          })
          resolve()
        },
        fail: (error: any) => {
          console.log('❌ 设备屏幕方向切换失败:', error)
          reject(error)
        }
      })
    })

  } catch (error) {
    console.error('屏幕方向切换API调用失败:', error)

    uni.hideLoading()

    // API调用失败的情况
    uni.showModal({
      title: '切换失败',
      content: `自动切换到${orientationText}失败。\n\n请尝试手动操作：\n\n1. 检查设备是否支持屏幕旋转\n2. 确保屏幕旋转锁定已关闭\n3. 物理旋转设备到${orientationText}方向`,
      showCancel: false,
      confirmText: '知道了',
      confirmColor: '#007AFF'
    })
  }
}

// 触摸相关状态
let touchStartX = 0
let touchStartY = 0
let touchStartTime = 0
let touchStartPage = 0 // 记录触摸开始时的页面

// 触摸开始
function onTouchStart(event: any) {
  const touch = event.touches[0] || event.changedTouches[0]
  touchStartX = touch.clientX
  touchStartY = touch.clientY
  touchStartTime = Date.now()
  touchStartPage = currentPage.value // 记录触摸开始时的页面
}

// 触摸结束
function onTouchEnd(event: any) {
  const touch = event.changedTouches[0]
  const touchEndX = touch.clientX
  const touchEndY = touch.clientY
  const touchEndTime = Date.now()

  // 计算滑动距离和时间
  const deltaX = touchEndX - touchStartX
  const deltaY = touchEndY - touchStartY
  const deltaTime = touchEndTime - touchStartTime

  // 判断是否为有效的水平滑动
  const minSwipeDistance = 50 // 最小滑动距离
  const maxSwipeTime = 500 // 最大滑动时间
  const maxVerticalDistance = 100 // 最大垂直偏移

  if (Math.abs(deltaX) > minSwipeDistance &&
      Math.abs(deltaY) < maxVerticalDistance &&
      deltaTime < maxSwipeTime) {

    if (deltaX < 0) {
      // 向左滑动（下一页）
      console.log('👆 检测到向左滑动手势', {
        touchStartPage: touchStartPage + 1,
        currentPage: currentPage.value + 1,
        totalPages: totalPages.value,
        pageChanged: touchStartPage !== currentPage.value,
        isLastPage: currentPage.value === totalPages.value - 1
      })

      // 只有在触摸开始时就已经是最后一页，且页面没有发生变化时，才触发阅读完成选择对话框
      if (touchStartPage === totalPages.value - 1 && touchStartPage === currentPage.value) {
        console.log('📚 在最后一页继续向左滑动，显示阅读完成选择对话框')
        handleLastPageNextAction()
      }
    } else {
      // 向右滑动（上一页）
      console.log('👆 检测到向右滑动手势', {
        touchStartPage: touchStartPage + 1,
        currentPage: currentPage.value + 1,
        totalPages: totalPages.value,
        pageChanged: touchStartPage !== currentPage.value,
        isFirstPage: currentPage.value === 0
      })

      // 如果当前是第一页，可以在这里添加相应逻辑（如返回上一本）
      if (currentPage.value === 0) {
        console.log('📚 在第一页向右滑动')
        // 暂时不实现返回上一本的功能
      }
    }
  }
}

// 切换控制栏显示
function toggleControls() {
  showControls.value = !showControls.value
  // 如果显示控制栏，同时隐藏提示
  if (showControls.value) {
    showTip.value = false
    // 启动自动隐藏定时器
    startControlsAutoHideTimer()
  } else {
    // 如果隐藏控制栏，清除定时器
    clearControlsAutoHideTimer()
  }
}

// 启动控制栏自动隐藏定时器
function startControlsAutoHideTimer() {
  // 清除之前的定时器
  clearControlsAutoHideTimer()

  console.log('⏰ 启动控制栏自动隐藏定时器，4秒后隐藏')
  controlsAutoHideTimer = setTimeout(() => {
    console.log('⏰ 控制栏自动隐藏定时器触发')
    hideControlsWithAnimation()
  }, 4000) // 4秒后自动隐藏
}

// 清除控制栏自动隐藏定时器
function clearControlsAutoHideTimer() {
  if (controlsAutoHideTimer) {
    clearTimeout(controlsAutoHideTimer)
    controlsAutoHideTimer = null
    console.log('⏰ 控制栏自动隐藏定时器已清除')
  }
}

// 标记用户正在操作
function markUserOperating() {
  isUserOperating.value = true
  console.log('👆 用户开始操作，暂停控制栏自动隐藏')

  // 清除之前的操作结束定时器
  if (userOperationTimer) {
    clearTimeout(userOperationTimer)
    userOperationTimer = null
  }

  // 设置操作结束检测定时器
  userOperationTimer = setTimeout(() => {
    isUserOperating.value = false
    console.log('👆 用户操作结束，重新启动控制栏自动隐藏定时器')

    // 用户操作结束后，重新启动控制栏自动隐藏定时器
    if (showControls.value) {
      startControlsAutoHideTimer()
    }
  }, USER_OPERATION_TIMEOUT)
}

// 清除用户操作定时器
function clearUserOperationTimer() {
  if (userOperationTimer) {
    clearTimeout(userOperationTimer)
    userOperationTimer = null
  }
}

// 检查是否应该阻止控制栏自动隐藏
function shouldPreventControlsAutoHide() {
  // 检查用户操作状态
  const isUserCurrentlyOperating = isUserOperating.value

  // 检查录音相关状态
  const isRecordingActive = recordingState.value === RecordingState.RECORDING ||
                           recordingState.value === RecordingState.PAUSED ||
                           recordingState.value === RecordingState.PREPARING ||
                           recordingState.value === RecordingState.STOPPING ||
                           recordingState.value === RecordingState.PROCESSING

  // 检查录音预览状态
  const isInRecordingPreview = showRecordingPreview.value

  // 检查弹窗和覆盖层状态
  const hasActiveDialog = showNextBookDialog.value ||
                         showReadingCompleteDialog.value ||
                         (showTranslation.value && translationText.value) ||
                         translationLoading.value

  // 检查其他交互状态
  const hasActiveInteraction = isTogglingAudio.value

  const shouldPrevent = isUserCurrentlyOperating || isRecordingActive || isInRecordingPreview || hasActiveDialog || hasActiveInteraction

  if (shouldPrevent) {
    console.log('⏰ 检测到阻止控制栏隐藏的条件:', {
      isUserCurrentlyOperating,
      isRecordingActive,
      isInRecordingPreview,
      hasActiveDialog,
      hasActiveInteraction,
      recordingState: recordingState.value
    })
  }

  return shouldPrevent
}

// 带动画效果隐藏控制栏
function hideControlsWithAnimation() {
  if (!showControls.value) {
    console.log('⏰ 控制栏已隐藏，跳过动画')
    return
  }

  // 检查是否应该阻止自动隐藏
  if (shouldPreventControlsAutoHide()) {
    console.log('⏰ 检测到阻止条件，延迟控制栏隐藏，重新启动定时器')
    // 重新启动定时器，延迟隐藏
    startControlsAutoHideTimer()
    return
  }

  console.log('🎭 开始控制栏淡出动画')

  // 在uni-app中，我们直接使用CSS transition来实现淡出效果
  // 通过修改showControls的值来触发CSS transition
  showControls.value = false
  console.log('🎭 控制栏淡出动画完成，控制栏已隐藏')
}

// 重置控制栏自动隐藏定时器（用户交互时调用）
function resetControlsAutoHideTimer() {
  if (showControls.value) {
    console.log('⏰ 用户交互，标记用户操作状态')
    // 标记用户正在操作，这会暂停控制栏自动隐藏
    markUserOperating()
    // 清除当前的自动隐藏定时器，等待用户操作结束后重新启动
    clearControlsAutoHideTimer()
  }
}

// 隐藏提示
function hideTip() {
  showTip.value = false
}

// 设置功能
function toggleSettings() {
  // 重置控制栏自动隐藏定时器
  resetControlsAutoHideTimer()

  uni.navigateTo({
    url: '/pages-sub/profile/reading-settings/index'
  })
}

// 收藏功能
async function toggleFavorite() {
  // 重置控制栏自动隐藏定时器
  resetControlsAutoHideTimer()

  if (!bookId.value) {
    uni.showToast({
      title: '绘本信息不完整',
      icon: 'none'
    })
    return
  }

  const originalState = isFavorite.value

  try {
    // 乐观更新UI
    isFavorite.value = !isFavorite.value

    const favoriteData: FavoriteOperationReqVO = {
      targetId: Number(bookId.value),
      targetType: 'book'
    }

    let response: any
    if (isFavorite.value) {
      // 添加收藏
      response = await addBookFavorite(favoriteData)
    } else {
      // 取消收藏
      response = await removeBookFavorite(favoriteData)
    }

    if (response && response.code === 0) {
      // 清除收藏相关缓存
      clearFavoritesCache()
      uni.showToast({
        title: isFavorite.value ? '已收藏' : '取消收藏',
        icon: 'success',
        duration: 1500
      })
      console.log('收藏操作成功:', isFavorite.value ? '已收藏' : '已取消收藏')
    } else {
      throw new Error(response?.msg || '操作失败')
    }
  } catch (error) {
    console.error('收藏操作失败:', error)

    // 回滚UI状态
    isFavorite.value = originalState

    uni.showToast({
      title: '操作失败，请重试',
      icon: 'none'
    })
  }
}

// 切换阅读模式
async function toggleReadingMode() {
  // 重置控制栏自动隐藏定时器
  resetControlsAutoHideTimer()

  readingMode.value = readingMode.value === 'image' ? 'text' : 'image'
  readingSettings.value.readingMode = readingMode.value

  // 保存设置到本地存储
  try {
    uni.setStorageSync('readingSettings', readingSettings.value)
  } catch (error) {
    console.log('保存设置失败:', error)
  }

  // 同步保存到服务器
  await saveSettingsToServer()

  uni.showToast({
    title: readingMode.value === 'image' ? '图片阅读模式' : '文字阅读模式',
    icon: 'none'
  })
}

// 翻译功能切换
function toggleTranslation() {
  // 重置控制栏自动隐藏定时器
  resetControlsAutoHideTimer()

  if (!isEnglishBook.value) {
    uni.showToast({
      title: '仅支持英文绘本翻译',
      icon: 'none'
    })
    return
  }

  // 检查当前页面是否有翻译内容
  const currentPageData = bookPages.value[currentPage.value]
  if (!currentPageData?.chineseTranslation) {
    uni.showToast({
      title: '当前页面暂无翻译',
      icon: 'none'
    })
    return
  }

  // 切换翻译显示状态
  showTranslation.value = !showTranslation.value

  // 显示提示信息
  uni.showToast({
    title: showTranslation.value ? '已切换到中文' : '已切换到英文',
    icon: 'none',
    duration: 1500
  })
}

// 关闭翻译
function closeTranslation() {
  showTranslation.value = false
  translationText.value = ''

  // 翻译关闭后，重新启动控制栏自动隐藏定时器
  if (showControls.value) {
    startControlsAutoHideTimer()
    console.log('📖 翻译关闭，重新启动控制栏自动隐藏定时器')
  }
}

// 原翻译功能（已禁用）
// async function toggleTranslation() {
//   if (!isEnglishBook.value) {
//     uni.showToast({
//       title: '仅支持英文绘本翻译',
//       icon: 'none'
//     })
//     return
//   }

//   if (showTranslation.value) {
//     // 隐藏翻译
//     showTranslation.value = false
//     translationText.value = ''
//   } else {
//     // 显示翻译
//     await loadTranslation()
//   }
// }

// 加载当前页面的翻译
async function loadTranslation() {
  if (!bookPages.value[currentPage.value]?.textContent) {
    uni.showToast({
      title: '当前页面无文本内容',
      icon: 'none'
    })
    return
  }

  const currentPageData = bookPages.value[currentPage.value]
  const sourceText = currentPageData.textContent
  const cacheKey = `${bookId.value}_${currentPage.value}_${sourceText}`

  try {
    translationLoading.value = true

    // 检查缓存
    if (translationCache.has(cacheKey)) {
      translationText.value = translationCache.get(cacheKey) || ''
      showTranslation.value = true
      console.log('翻译从缓存加载')
      return
    }

    // 调用翻译API
    const response = await translateText({
      text: sourceText,
      sourceLanguage: 'en',
      targetLanguage: 'zh',
      bookId: Number(bookId.value),
      pageId: currentPageData.id
    })

    if (response && response.data && response.data.code === 0) {
      const translatedText = response.data.data.translatedText
      translationText.value = translatedText
      showTranslation.value = true

      // 缓存翻译结果
      translationCache.set(cacheKey, translatedText)

      // 保存到本地存储
      saveTranslationToLocal(cacheKey, translatedText)

      console.log('翻译成功')
    } else {
      throw new Error(response?.data?.msg || '翻译失败')
    }
  } catch (error) {
    console.error('翻译失败:', error)

    // 尝试从本地缓存加载
    const localTranslation = getTranslationFromLocal(cacheKey)
    if (localTranslation) {
      translationText.value = localTranslation
      showTranslation.value = true
      uni.showToast({
        title: '已显示离线翻译',
        icon: 'none'
      })
    } else {
      uni.showToast({
        title: '翻译失败，请重试',
        icon: 'none'
      })
    }
  } finally {
    translationLoading.value = false
  }
}

// 保存翻译到本地存储
function saveTranslationToLocal(key: string, translation: string) {
  try {
    const translations = uni.getStorageSync('translations') || {}
    translations[key] = translation
    uni.setStorageSync('translations', translations)
  } catch (error) {
    console.error('保存翻译到本地失败:', error)
  }
}

// 从本地存储获取翻译
function getTranslationFromLocal(key: string): string | null {
  try {
    const translations = uni.getStorageSync('translations') || {}
    return translations[key] || null
  } catch (error) {
    console.error('从本地获取翻译失败:', error)
    return null
  }
}



// 音频播放功能
async function toggleAudio() {
  console.log('🎵 toggleAudio 被调用，当前 isAudioPlaying:', isAudioPlaying.value)
  console.log('🔍 调用栈:', new Error().stack)

  // 重置控制栏自动隐藏定时器
  resetControlsAutoHideTimer()

  // 防抖处理，防止快速重复点击
  if (audioControlDebounceTimer) {
    console.log('⚠️ 防抖：忽略快速重复的音频控制操作')
    return
  }

  audioControlDebounceTimer = setTimeout(() => {
    audioControlDebounceTimer = null
  }, 500) // 500ms 防抖

  // 直接根据当前播放状态决定操作，不需要冲突检查
  // 因为这是用户主动的播放/暂停切换操作

  if (isAudioPlaying.value) {
    console.log('🔇 当前正在播放，用户点击暂停')
    // 停止音频播放（标记为用户手动操作）
    stopAudioPlayback('用户手动暂停', true)

    // 如果开启了自动翻页，重新启动延迟翻页
    if (readingSettings.value.autoTurnPage) {
      startAutoTurnPage()
    }

    uni.showToast({
      title: '音频已暂停',
      icon: 'none'
    })
  } else {
    console.log('▶️ 当前未播放，用户点击播放')
    console.log('🔍 用户手动点击播放按钮，当前 userManuallyStopped:', userManuallyStopped)

    // 检查是否有录音冲突
    const conflict = checkAudioConflict()
    if (conflict.hasConflict && conflict.conflictType === 'recording_active') {
      console.log('⚠️ 检测到录音冲突，停止录音以播放音频')
      forceStopRecording()
      await new Promise(resolve => setTimeout(resolve, 500))
    }

    // 用户手动开始播放音频，清除手动暂停标记
    userManuallyStopped = false
    console.log('🎵 用户手动开始播放音频，清除手动暂停标记，新值:', userManuallyStopped)

    // 检查当前页面是否有音频资源
    const currentPageData = bookPages.value[currentPage.value]
    if (!currentPageData) {
      uni.showToast({
        title: '页面数据不存在',
        icon: 'none'
      })
      return
    }

    // 检查是否有可用的音频
    const hasOfficialAudio = !!currentPageData.officialAudioUrl
    const hasUserAudio = hasUserRecordingComputed.value

    if (!hasOfficialAudio && !hasUserAudio) {
      uni.showToast({
        title: '当前页面暂无音频资源',
        icon: 'none'
      })
      return
    }

    // 开始音频播放
    startAutoAudio()
    const sourceText = audioSource.value === 'official' ? '官方音频' : '用户录制'
    uni.showToast({
      title: `播放${sourceText}`,
      icon: 'none'
    })
  }

  // 同步音频状态
  syncAudioState()
}

// 切换音频来源
async function toggleAudioSource() {
  // 重置控制栏自动隐藏定时器
  resetControlsAutoHideTimer()

  // 防止重复点击
  if (isTogglingAudio.value) {
    console.log('🔄 音频切换中，忽略重复点击')
    return
  }

  isTogglingAudio.value = true

  try {
    // 如果当前正在播放音频，先停止
    if (isAudioPlaying.value) {
      stopAudioPlayback('切换音频来源')
    }

    // 当前音频来源
    const currentSource = audioSource.value

  // 如果当前是官方音频，准备切换到用户配音
  if (currentSource === 'official') {
    // 显示加载提示
    uni.showLoading({
      title: '检查用户录音...',
      mask: true
    })

    try {
      // 从服务器获取最新的用户录音数据
      await loadCurrentPageUserRecording()

      // 检查当前页面是否有用户配音
      const userRecording = getCurrentPageUserRecording()

      uni.hideLoading()

      if (userRecording) {
        // 有用户配音，正常切换
        audioSource.value = 'user'

        // 保存用户偏好到本地存储
        try {
          uni.setStorageSync('audioSource', audioSource.value)
        } catch (error) {
          console.log('保存音频来源设置失败:', error)
        }

        // 显示录音信息
        const qualityText = recordingConfig[userRecording.quality]?.description || '未知质量'
        const durationText = formatRecordingTime(userRecording.duration)
        const sourceText = serverUserRecording.value ? '服务器录音' : '本地录音'

        uni.showToast({
          title: `已切换到${sourceText} (${qualityText}, ${durationText})`,
          icon: 'none',
          duration: 2000
        })

        console.log('🎙️ 已切换到用户录音:', userRecording.id || userRecording.filePath, '来源:', sourceText)
      } else {
        // 无用户配音，保持官方音频模式，显示提示
        uni.showToast({
          title: '当前页面暂无用户配音，请先录制配音',
          icon: 'none',
          duration: 3000
        })
        console.log('🎙️ 当前页面无用户配音，保持官方音频模式')
      }
    } catch (error) {
      uni.hideLoading()
      console.error('❌ 获取用户录音失败:', error)
      uni.showToast({
        title: '获取用户录音失败',
        icon: 'none',
        duration: 2000
      })
    }
  } else {
    // 从用户配音切换回官方音频，无需检测，直接切换
    audioSource.value = 'official'

    // 保存用户偏好到本地存储
    try {
      uni.setStorageSync('audioSource', audioSource.value)
    } catch (error) {
      console.log('保存音频来源设置失败:', error)
    }

    uni.showToast({
      title: '已切换到官方音频',
      icon: 'none',
      duration: 2000
    })

    console.log('🎵 已切换到官方音频')
  }
  } finally {
    // 重置切换状态
    isTogglingAudio.value = false
  }
}

// 格式化录音时长
function formatRecordingTime(seconds: number): string {
  const minutes = Math.floor(seconds / 60)
  const remainingSeconds = seconds % 60
  return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`
}

// 检查音频播放冲突
function checkAudioConflict(): { hasConflict: boolean, conflictType: string, suggestion: string } {
  let hasConflict = false
  let conflictType = ''
  let suggestion = ''

  // 检查录音状态冲突 - 只有在真正录音的状态下才认为有冲突
  if (recordingState.value === RecordingState.RECORDING ||
      recordingState.value === RecordingState.PAUSED ||
      recordingState.value === RecordingState.PREPARING ||
      recordingState.value === RecordingState.STOPPING ||
      recordingState.value === RecordingState.PROCESSING) {
    hasConflict = true
    conflictType = 'recording_active'
    suggestion = '当前正在录音，请先停止录音再播放音频'
  }

  // 检查音频播放状态冲突
  if (isAudioPlaying.value && !hasConflict) {
    hasConflict = true
    conflictType = 'audio_playing'
    suggestion = '当前正在播放音频，请先停止播放再进行其他操作'
  }

  return { hasConflict, conflictType, suggestion }
}

// 解决音频冲突
async function resolveAudioConflict(operation: 'play' | 'record'): Promise<boolean> {
  const conflict = checkAudioConflict()

  if (!conflict.hasConflict) {
    return true // 无冲突，可以继续
  }

  console.log('⚠️ 检测到音频冲突:', conflict)

  try {
    if (conflict.conflictType === 'recording_active') {
      if (operation === 'play') {
        // 播放音频时遇到录音冲突，停止录音
        console.log('🔇 停止录音以播放音频')
        forceStopRecording()
        await new Promise(resolve => setTimeout(resolve, 500))
        return true
      } else {
        // 录音时遇到录音冲突（不应该发生）
        console.log('⚠️ 录音冲突，无法继续')
        return false
      }
    }

    if (conflict.conflictType === 'audio_playing') {
      if (operation === 'record') {
        // 录音时遇到播放冲突，停止播放
        console.log('🔇 停止音频播放以开始录音')
        stopAudioPlayback('开始录音')
        await new Promise(resolve => setTimeout(resolve, 500))
        return true
      } else {
        // 播放时遇到播放冲突，停止当前播放
        console.log('🔇 停止当前播放以开始新播放')
        stopAudioPlayback('切换音频')
        await new Promise(resolve => setTimeout(resolve, 300))
        return true
      }
    }

    return false
  } catch (error) {
    console.error('解决音频冲突失败:', error)
    return false
  }
}

// 音频状态同步
function syncAudioState() {
  // 修复状态不一致问题：如果录音状态是错误或完成，但isRecording仍为true，自动修复
  if ((recordingState.value === RecordingState.ERROR || recordingState.value === RecordingState.COMPLETED || recordingState.value === RecordingState.IDLE) && isRecording.value) {
    console.warn('⚠️ 检测到录音状态不一致，自动修复:', {
      recordingState: recordingState.value,
      isRecording: isRecording.value
    })
    isRecording.value = false
  }

  // 同步音频播放状态
  const audioPlaying = isAudioPlaying.value
  // 只有在真正录音的状态下才认为是录音中（排除错误和完成状态）
  const recording = recordingState.value === RecordingState.RECORDING ||
                   recordingState.value === RecordingState.PAUSED ||
                   recordingState.value === RecordingState.PREPARING ||
                   recordingState.value === RecordingState.STOPPING ||
                   recordingState.value === RecordingState.PROCESSING

  // 确保状态一致性
  if (audioPlaying && recording) {
    console.warn('⚠️ 检测到音频状态不一致：同时播放和录音')
    // 优先保持录音状态，停止音频播放
    stopAudioPlayback('状态同步')
  }

  // 更新UI状态
  const stateInfo = {
    audioPlaying,
    recording,
    audioSource: audioSource.value,
    recordingState: recordingState.value,
    hasUserRecording: hasUserRecordingComputed.value
  }

  console.log('🔄 音频状态同步:', stateInfo)

  return stateInfo
}

// 页面切换时的音频状态处理
async function handlePageChangeAudioState() {
  console.log('📄 页面切换，处理音频状态')

  // 先加载当前页面的用户录音数据
  await loadCurrentPageUserRecording()

  // 检查当前页面是否有用户录音
  const hasUserAudio = hasUserRecordingComputed.value

  // 如果当前音频源是用户录音，但当前页面没有用户录音，切换到官方音频
  if (audioSource.value === 'user' && !hasUserAudio) {
    console.log('🔄 当前页面无用户录音，自动切换到官方音频')
    audioSource.value = 'official'

    try {
      uni.setStorageSync('audioSource', audioSource.value)
    } catch (error) {
      console.log('保存音频来源设置失败:', error)
    }
  }

  // 同步音频状态
  syncAudioState()
}

// 检查并自动切换音频模式（进入页面时调用）
async function checkAndSwitchAudioMode() {
  console.log('🔍 检查音频模式，当前音频源:', audioSource.value)

  // 如果当前是用户音频模式，检查是否有用户录音
  if (audioSource.value === 'user') {
    const hasUserAudio = hasUserRecordingComputed.value

    if (!hasUserAudio) {
      console.log('🔄 进入页面时检测到用户音频模式但无用户录音，自动切换到官方音频')
      audioSource.value = 'official'

      // 保存设置到本地存储
      try {
        uni.setStorageSync('audioSource', audioSource.value)
      } catch (error) {
        console.log('保存音频来源设置失败:', error)
      }

      // 显示提示
      uni.showToast({
        title: '当前页面无用户录音，已切换到官方音频',
        icon: 'none',
        duration: 2000
      })
    } else {
      console.log('✅ 用户音频模式且有用户录音，保持当前模式')
    }
  } else {
    console.log('✅ 当前为官方音频模式，无需切换')
  }

  // 同步音频状态
  syncAudioState()
}

// 初始化录音权限
async function initRecordingPermission() {
  try {
    console.log('🔧 初始化录音权限管理...')

    // 重置权限状态
    recordingPermissionStatus.value = 'unknown'
    permissionCheckRetryCount.value = 0

    // 执行初始权限检查
    const hasPermission = await checkRecordingPermission()

    if (hasPermission) {
      console.log('✅ 录音权限初始化成功')
    } else {
      console.log('⚠️ 录音权限初始化失败，用户需要手动授权')
    }

    // 设置权限状态监听器（页面显示时重新检查）
    setupPermissionMonitoring()

  } catch (error) {
    console.error('❌ 录音权限初始化失败:', error)
    recordingPermissionStatus.value = 'unknown'
  }
}

// 设置权限监控
function setupPermissionMonitoring() {
  // 页面显示时重新检查权限（用户可能在设置中修改了权限）
  const originalOnShow = onShow

  // 监听页面显示事件
  uni.onAppShow(() => {
    console.log('📱 应用重新显示，检查录音权限状态')

    // 延迟检查，避免频繁调用
    setTimeout(async () => {
      if (recordingPermissionStatus.value === 'denied' || recordingPermissionStatus.value === 'temporarily_denied') {
        console.log('🔄 重新检查录音权限状态')
        await checkRecordingPermission()
      }
    }, 1000)
  })
}

// 获取权限状态描述
function getPermissionStatusDescription(status: string): string {
  switch (status) {
    case 'granted':
      return '已授权'
    case 'denied':
      return '已拒绝'
    case 'temporarily_denied':
      return '临时拒绝'
    case 'checking':
      return '检查中'
    case 'unknown':
    default:
      return '未知'
  }
}

// 检查录音权限
async function checkRecordingPermission(): Promise<boolean> {
  if (permissionCheckInProgress.value) {
    console.log('权限检查正在进行中，跳过重复检查')
    return recordingPermissionStatus.value === 'granted'
  }

  try {
    permissionCheckInProgress.value = true
    recordingPermissionStatus.value = 'checking'

    console.log('🔍 开始检查录音权限...')

    return new Promise((resolve) => {
      uni.getSetting({
        success: (res) => {
          console.log('📋 获取权限设置成功:', res.authSetting)

          const recordPermission = res.authSetting['scope.record']

          if (recordPermission === true) {
            recordingPermissionStatus.value = 'granted'
            console.log('✅ 录音权限已授权')
            resolve(true)
          } else if (recordPermission === false) {
            recordingPermissionStatus.value = 'denied'
            console.log('❌ 录音权限被拒绝')
            resolve(false)
          } else {
            // 权限未设置，需要请求权限
            console.log('❓ 录音权限未设置，需要请求权限')
            requestRecordingPermission().then(resolve)
          }
        },
        fail: (error) => {
          console.error('❌ 获取权限设置失败:', error)
          recordingPermissionStatus.value = 'unknown'

          // 权限检查失败时的重试逻辑
          if (permissionCheckRetryCount.value < maxPermissionRetries) {
            permissionCheckRetryCount.value++
            console.log(`🔄 权限检查失败，${2000}ms后进行第${permissionCheckRetryCount.value}次重试`)

            setTimeout(() => {
              checkRecordingPermission().then(resolve)
            }, 2000)
          } else {
            console.log('❌ 权限检查重试次数已达上限')
            resolve(false)
          }
        }
      })
    })
  } finally {
    permissionCheckInProgress.value = false
  }
}

// 请求录音权限
async function requestRecordingPermission(): Promise<boolean> {
  console.log('📝 请求录音权限...')

  return new Promise((resolve) => {
    uni.authorize({
      scope: 'scope.record',
      success: () => {
        console.log('✅ 录音权限授权成功')
        recordingPermissionStatus.value = 'granted'
        permissionCheckRetryCount.value = 0 // 重置重试计数
        resolve(true)
      },
      fail: (error) => {
        console.error('❌ 录音权限授权失败:', error)

        // 分析失败原因
        if (error.errMsg && error.errMsg.includes('deny')) {
          recordingPermissionStatus.value = 'denied'
          console.log('🚫 用户拒绝了录音权限')
        } else {
          recordingPermissionStatus.value = 'temporarily_denied'
          console.log('⏳ 录音权限临时获取失败')
        }

        resolve(false)
      }
    })
  })
}

// 显示权限被拒绝的对话框
function showPermissionDeniedDialog(reason: string = '录音权限被拒绝') {
  const content = `${reason}，无法使用录音功能。

请按以下步骤开启权限：
1. 点击右上角"..."菜单
2. 选择"设置"
3. 开启"录音"权限
4. 返回重试`

  uni.showModal({
    title: '需要录音权限',
    content,
    confirmText: '去设置',
    cancelText: '取消',
    success: (res) => {
      if (res.confirm) {
        // 引导用户去设置页面
        uni.openSetting({
          success: (settingRes) => {
            console.log('用户设置结果:', settingRes.authSetting)

            if (settingRes.authSetting['scope.record']) {
              recordingPermissionStatus.value = 'granted'
              uni.showToast({
                title: '权限已开启',
                icon: 'success'
              })
            } else {
              recordingPermissionStatus.value = 'denied'
              uni.showToast({
                title: '权限仍未开启',
                icon: 'none'
              })
            }
          },
          fail: (error) => {
            console.error('打开设置页面失败:', error)
            uni.showToast({
              title: '无法打开设置页面',
              icon: 'none'
            })
          }
        })
      }
    }
  })
}

// 初始化录音管理器
function initRecorderManager() {
  try {
    console.log('🎤 初始化录音管理器...')
    recorderManager.value = uni.getRecorderManager()

    if (recorderManager.value) {
      // 录音开始事件
      recorderManager.value.onStart(() => {
        console.log('🎤 录音开始事件触发')
        console.log('🔍 设置前状态 - isRecording:', isRecording.value, 'recordingState:', recordingState.value)

        recordingState.value = RecordingState.RECORDING
        isRecording.value = true
        recordingPaused.value = false
        recordingDuration.value = 0
        recordingStartTime.value = Date.now()

        console.log('🔍 设置后状态 - isRecording:', isRecording.value, 'recordingState:', recordingState.value)

        startRecordingTimer()
        startVolumeMonitoring()

        uni.showToast({
          title: '开始录音',
          icon: 'none',
          duration: 1000
        })
      })

      // 录音暂停事件（如果支持）
      if (typeof recorderManager.value.onPause === 'function') {
        recorderManager.value.onPause(() => {
          console.log('⏸️ 录音暂停')
          recordingState.value = RecordingState.PAUSED
          recordingPaused.value = true
          stopRecordingTimer()
          stopVolumeMonitoring()

          uni.showToast({
            title: '录音已暂停',
            icon: 'none',
            duration: 1000
          })
        })
      }

      // 录音恢复事件（如果支持）
      if (typeof recorderManager.value.onResume === 'function') {
        recorderManager.value.onResume(() => {
          console.log('▶️ 录音恢复')
          recordingState.value = RecordingState.RECORDING
          recordingPaused.value = false
          startRecordingTimer()
          startVolumeMonitoring()

          uni.showToast({
            title: '录音已恢复',
            icon: 'none',
            duration: 1000
          })
        })
      }

      // 录音结束事件
      recorderManager.value.onStop((res) => {
        console.log('⏹️ 录音结束事件触发:', res)
        console.log('🔍 录音文件路径:', res.tempFilePath)
        console.log('🔍 录音文件大小:', res.fileSize)
        console.log('🔍 当前录音时长:', recordingDuration.value)
        console.log('🔍 停止前状态 - isRecording:', isRecording.value, 'recordingState:', recordingState.value)

        recordingState.value = RecordingState.PROCESSING
        isRecording.value = false
        recordingPaused.value = false

        console.log('🔍 停止后状态 - isRecording:', isRecording.value, 'recordingState:', recordingState.value)

        stopRecordingTimer()
        stopVolumeMonitoring()

        // 保存录音文件信息
        if (res.tempFilePath) {
          recordingFilePath.value = res.tempFilePath
          recordingFileSize.value = res.fileSize || 0
          console.log('✅ 录音文件信息已保存')
        } else {
          console.error('❌ 录音文件路径为空')
        }

        console.log('🔍 准备调用handleRecordingComplete')
        handleRecordingComplete(res)
      })

      // 录音错误事件
      recorderManager.value.onError((err) => {
        console.error('❌ 录音错误:', err)
        recordingState.value = RecordingState.ERROR
        isRecording.value = false
        recordingPaused.value = false
        stopRecordingTimer()
        stopVolumeMonitoring()

        // 使用新的错误处理系统
        handleRecordingError(err, '录制')

        // 如果是权限问题，更新权限状态
        if (err.errMsg && err.errMsg.includes('permission')) {
          recordingPermissionStatus.value = 'denied'
        }
      })

      // 录音帧数据事件（可用于实时音量检测）
      recorderManager.value.onFrameRecorded((res) => {
        // 实现音量可视化
        if (res.frameBuffer) {
          updateVolumeLevel(res.frameBuffer)
        }
      })

      console.log('✅ 录音管理器初始化成功')
    } else {
      throw new Error('无法获取录音管理器')
    }
  } catch (error) {
    console.error('❌ 初始化录音管理器失败:', error)
    recordingState.value = RecordingState.ERROR
    isRecording.value = false

    uni.showToast({
      title: '录音功能不可用',
      icon: 'none'
    })
  }
}

// 开始录音计时
function startRecordingTimer() {
  console.log('⏰ 开始录音计时器')

  // 先清除可能存在的计时器
  if (recordingTimer.value) {
    clearInterval(recordingTimer.value)
    recordingTimer.value = null
  }

  recordingTimer.value = setInterval(() => {
    recordingDuration.value += 1
    console.log('⏰ 录音时长更新:', recordingDuration.value, '秒')
  }, 1000)

  console.log('✅ 录音计时器已启动，ID:', recordingTimer.value)
}

// 停止录音计时
function stopRecordingTimer() {
  console.log('⏰ 停止录音计时器，当前ID:', recordingTimer.value)

  if (recordingTimer.value) {
    clearInterval(recordingTimer.value)
    recordingTimer.value = null
    console.log('✅ 录音计时器已停止')
  } else {
    console.log('⚠️ 录音计时器已经是null，无需停止')
  }
}

// 保存临时录音到内存（只保存当前页面最新录音）
const saveTemporaryRecording = (filePath: string, duration: number) => {
  try {
    console.log('💾 保存临时录音:', filePath)

    currentPageRecording.value = {
      filePath: filePath,
      duration: duration,
      quality: recordingQuality.value,
      createTime: new Date().toISOString(),
      bookId: Number(bookId.value),
      pageNumber: currentPage.value
    }

    console.log('✅ 临时录音已保存到内存')
    return currentPageRecording.value
  } catch (error) {
    console.error('❌ 保存临时录音失败:', error)
    throw error
  }
}

// 计算录音优先级（分数越低越优先删除）
function calculateRecordingPriority(recording: any): number {
  let score = 0

  // 时间因素（越旧分数越低）
  const daysSinceCreation = (Date.now() - new Date(recording.createTime).getTime()) / (1000 * 60 * 60 * 24)
  score += Math.min(daysSinceCreation * 10, 100) // 最多100分

  // 播放次数（播放越多分数越高）
  score += (recording.playCount || 0) * 20

  // 上传状态（已上传的分数更低）
  if (recording.uploaded) {
    score -= 50
  }

  // 活跃状态（活跃录音分数很高）
  if (recording.isActive) {
    score += 1000
  }

  // 最近播放（最近播放的分数更高）
  if (recording.lastPlayTime) {
    const daysSincePlay = (Date.now() - new Date(recording.lastPlayTime).getTime()) / (1000 * 60 * 60 * 24)
    score += Math.max(50 - daysSincePlay * 5, 0)
  }

  return score
}

// 判断是否为最近的录音
function isRecentRecording(recording: any): boolean {
  const daysSinceCreation = (Date.now() - new Date(recording.createTime).getTime()) / (1000 * 60 * 60 * 24)
  return daysSinceCreation < 1 // 1天内的录音
}

// 处理录音完成
async function handleRecordingComplete(res: any) {
  try {
    recordingState.value = RecordingState.PROCESSING

    if (!res.tempFilePath) {
      throw new Error('录音文件路径为空')
    }

    console.log('🎤 录音完成，开始处理:', res)

    // 显示处理进度
    uni.showLoading({
      title: '处理录音中...',
      mask: true
    })

    // 准备预览数据
    previewRecordingData.value = {
      tempFilePath: res.tempFilePath,
      duration: recordingDuration.value,
      fileSize: res.fileSize || 0,
      quality: recordingQuality.value
    }

    // 切换到预览状态
    recordingState.value = RecordingState.PREVIEW
    isRecording.value = false
    showRecordingPreview.value = true

    uni.hideLoading()

    console.log('🎤 录音预览准备完成:', previewRecordingData.value)

    // 强制刷新覆盖层状态，确保隐藏
    nextTick(() => {
      console.log('🔄 录音完成后强制检查覆盖层状态')
      console.log('🔍 isRecording:', isRecording.value, 'recordingState:', recordingState.value)

      // 如果状态已完成但仍在录音，强制重置
      if (recordingState.value === RecordingState.COMPLETED && isRecording.value) {
        console.log('⚠️ 检测到状态不一致，强制重置')
        isRecording.value = false
      }
    })

    uni.showToast({
      title: '录音保存成功',
      icon: 'success'
    })

    console.log('✅ 录音预览准备完成')

    // 显示预览提示
    uni.showToast({
      title: '录音完成，请预览',
      icon: 'success',
      duration: 2000
    })

  } catch (error) {
    console.error('❌ 处理录音失败:', error)
    recordingState.value = RecordingState.ERROR
    isRecording.value = false
    uni.hideLoading()

    uni.showToast({
      title: error.message || '录音处理失败',
      icon: 'none'
    })
  }
}

// 录音预览相关函数
// 处理预览覆盖层点击
function handlePreviewOverlayClick() {
  // 在小程序环境中，简化点击处理逻辑
  // 由于小程序的事件对象结构可能不同，我们不依赖classList
  console.log('🎵 预览覆盖层被点击')

  // 可以在这里添加关闭预览的逻辑，或者什么都不做
  // 目前保持预览界面打开，用户需要通过按钮操作
}

// 切换预览播放状态
async function togglePreviewPlayback() {
  if (!previewRecordingData.value) {
    uni.showToast({
      title: '录音数据不存在',
      icon: 'none'
    })
    return
  }

  if (isPreviewPlaying.value) {
    // 暂停播放
    stopPreviewPlayback()
  } else {
    // 开始播放
    await startPreviewPlayback()
  }
}

// 开始预览播放
async function startPreviewPlayback() {
  try {
    if (previewAudioContext.value) {
      previewAudioContext.value.destroy()
    }

    previewAudioContext.value = uni.createInnerAudioContext()
    previewAudioContext.value.src = previewRecordingData.value.tempFilePath

    previewAudioContext.value.onPlay(() => {
      isPreviewPlaying.value = true
      console.log('🎵 预览播放开始')
    })

    previewAudioContext.value.onEnded(() => {
      isPreviewPlaying.value = false
      console.log('🎵 预览播放结束')
    })

    previewAudioContext.value.onError((error) => {
      console.error('❌ 预览播放错误:', error)
      isPreviewPlaying.value = false
      uni.showToast({
        title: '播放失败',
        icon: 'none'
      })
    })

    previewAudioContext.value.play()
  } catch (error) {
    console.error('❌ 开始预览播放失败:', error)
    uni.showToast({
      title: '播放失败',
      icon: 'none'
    })
  }
}

// 停止预览播放
function stopPreviewPlayback() {
  if (previewAudioContext.value) {
    previewAudioContext.value.stop()
    isPreviewPlaying.value = false
  }
}

// 从预览重新录制
async function rerecordFromPreview() {
  // 停止预览播放
  stopPreviewPlayback()

  // 关闭预览界面
  showRecordingPreview.value = false
  previewRecordingData.value = null

  // 重置录音状态
  recordingState.value = RecordingState.IDLE

  // 开始新的录音
  await startRecording()
}

// 取消录音预览
function cancelRecordingPreview() {
  // 停止预览播放
  stopPreviewPlayback()

  // 清理预览数据
  showRecordingPreview.value = false
  previewRecordingData.value = null

  // 重置录音状态
  recordingState.value = RecordingState.IDLE
  isRecording.value = false

  // 录音取消后，重新启动控制栏自动隐藏定时器
  if (showControls.value) {
    startControlsAutoHideTimer()
    console.log('🎤 录音取消，重新启动控制栏自动隐藏定时器')
  }

  uni.showToast({
    title: '已取消录音',
    icon: 'none'
  })
}

// 确认录音上传
async function confirmRecordingUpload() {
  if (!previewRecordingData.value) {
    uni.showToast({
      title: '录音数据不存在',
      icon: 'none'
    })
    return
  }

  try {
    // 停止预览播放
    stopPreviewPlayback()

    // 1. 音频时长验证
    const duration = previewRecordingData.value.duration
    console.log('🎤 验证录音时长:', duration, '秒')

    if (duration < 1) {
      uni.showToast({
        title: '录音时长过短，至少需要1秒',
        icon: 'none',
        duration: 2000
      })
      return
    }

    if (duration >= 60) {
      uni.showToast({
        title: '录音时长过长，最多59秒',
        icon: 'none',
        duration: 2000
      })
      return
    }

    // 获取当前页面数据
    const currentPageData = bookPages.value[currentPage.value]
    if (!currentPageData) {
      throw new Error('页面数据不存在')
    }

    console.log('🎤 当前页面数据:', {
      id: currentPageData.id,
      pageNumber: currentPageData.pageNumber,
      bookId: bookId.value
    })

    // 2. 服务器录音覆盖确认
    // 显示检查进度
    uni.showLoading({
      title: '检查录音状态...',
      mask: true
    })

    // 使用getUserRecordingByPage API检查服务器端录音
    let hasServerRecording = false
    try {
      const serverRecordingResponse = await getUserRecordingByPage(currentPageData.id)
      if (serverRecordingResponse && serverRecordingResponse.code === 0 && serverRecordingResponse.data) {
        hasServerRecording = true
        console.log('🎤 检测到服务器端已有录音:', serverRecordingResponse.data)
      }
    } catch (error) {
      console.log('🎤 检查服务器录音时出错（可能是没有录音）:', error)
      hasServerRecording = false
    }

    if (hasServerRecording) {
      uni.hideLoading()

      // 显示覆盖确认对话框
      const confirmResult = await new Promise<boolean>((resolve) => {
        uni.showModal({
          title: '覆盖录音',
          content: '当前页面已有录音，是否覆盖？',
          confirmText: '确认',
          cancelText: '取消',
          success: (res) => {
            resolve(res.confirm)
          },
          fail: () => {
            resolve(false)
          }
        })
      })

      if (!confirmResult) {
        // 用户取消覆盖
        uni.showToast({
          title: '已取消上传',
          icon: 'none'
        })
        return
      }
    }

    // 显示上传进度
    uni.showLoading({
      title: '上传录音中...',
      mask: true
    })

    // 上传录音到服务器
    const uploadParams = {
      bookId: Number(bookId.value),
      pageId: currentPageData.id, // 添加pageId参数
      pageNumber: currentPageData.pageNumber,
      file: previewRecordingData.value.tempFilePath,
      duration: previewRecordingData.value.duration,
      quality: previewRecordingData.value.quality
    }

    console.log('🎤 上传录音参数:', uploadParams)

    const uploadResult = await uploadRecording(uploadParams)

    console.log('🎤 上传录音结果:', uploadResult)

    // 保存临时录音到内存
    const recordingData = saveTemporaryRecording(
      previewRecordingData.value.tempFilePath,
      previewRecordingData.value.duration
    )

    // 自动切换到用户录制音频
    audioSource.value = 'user'
    try {
      uni.setStorageSync('audioSource', audioSource.value)
    } catch (error) {
      console.log('保存音频来源设置失败:', error)
    }

    // 关闭预览界面
    showRecordingPreview.value = false
    previewRecordingData.value = null

    // 重置录音状态
    recordingState.value = RecordingState.COMPLETED
    isRecording.value = false

    // 录音上传完成后，重新启动控制栏自动隐藏定时器
    if (showControls.value) {
      startControlsAutoHideTimer()
      console.log('🎤 录音上传完成，重新启动控制栏自动隐藏定时器')
    }

    // 如果是配音作业，检查是否所有页面都已录音完成
    if (fromAssignment.value && assignmentId.value && requirementType.value === 'audio') {
      await checkAndSubmitAudioAssignmentCompletion()
    }

    uni.hideLoading()

    uni.showToast({
      title: '录音上传成功',
      icon: 'success'
    })

    console.log('✅ 录音上传完成:', uploadResult)

    // 清除临时录音数据，优先使用服务器端录音
    currentPageRecording.value = null

    // 重新加载用户录音数据，这样用户就能立即切换到服务器端的录音
    await loadCurrentPageUserRecording()



  } catch (error) {
    console.error('❌ 确认录音上传失败:', error)
    uni.hideLoading()

    uni.showToast({
      title: error.message || '上传录音失败',
      icon: 'none'
    })
  }
}

// 录制功能
// 切换录音状态（开始/暂停/停止）
function toggleRecording() {
  // 重置控制栏自动隐藏定时器
  resetControlsAutoHideTimer()

  console.log('🔍 toggleRecording 被调用')
  console.log('🔍 当前录音状态:', recordingState.value)
  console.log('🔍 录音管理器存在:', !!recorderManager.value)
  console.log('🔍 支持暂停恢复:', supportsPauseResume.value)

  if (!recorderManager.value) {
    console.log('❌ 录音管理器不存在')
    uni.showToast({
      title: '录音功能不可用',
      icon: 'none'
    })
    return
  }

  const currentState = recordingState.value

  switch (currentState) {
    case RecordingState.IDLE:
    case RecordingState.COMPLETED:
    case RecordingState.ERROR:
      console.log('▶️ 准备开始录音')
      startRecording()
      break

    case RecordingState.RECORDING:
      console.log('⏹️ 录音中，准备停止录音')
      // 如果支持暂停，则暂停；否则停止录音
      if (supportsPauseResume.value) {
        console.log('⏸️ 调用暂停录音')
        pauseRecording()
      } else {
        console.log('⏹️ 调用停止录音')
        stopRecording()
      }
      break

    case RecordingState.PAUSED:
      console.log('▶️ 准备恢复录音')
      resumeRecording()
      break

    case RecordingState.PREPARING:
    case RecordingState.STOPPING:
    case RecordingState.PROCESSING:
      // 这些状态下不允许操作
      console.log('⚠️ 当前状态不允许切换:', currentState)
      uni.showToast({
        title: '录音正在处理中，请稍候',
        icon: 'none'
      })
      break

    default:
      console.log('⚠️ 未知录音状态:', currentState)
  }
}

// 完全停止录音（不管当前状态）
function forceStopRecording() {
  try {
    console.log('🛑 强制停止录音，当前状态:', recordingState.value)

    // 如果当前正在录音，使用正常的停止流程
    if (recordingState.value === RecordingState.RECORDING || recordingState.value === RecordingState.PAUSED) {
      console.log('🛑 使用正常停止流程')
      stopRecording()
      return
    }

    // 如果状态异常，执行强制清理
    console.log('🛑 执行强制清理')

    // 停止所有定时器
    stopRecordingTimer()
    stopVolumeMonitoring()

    // 尝试调用录音管理器的停止方法
    if (recorderManager.value) {
      try {
        if (typeof recorderManager.value.stop === 'function') {
          console.log('🛑 调用录音管理器停止方法')
          recorderManager.value.stop()
        }
      } catch (error) {
        console.log('录音管理器停止失败:', error)
      }
    }

    // 强制重置所有录音相关状态
    recordingState.value = RecordingState.IDLE
    isRecording.value = false
    recordingPaused.value = false
    recordingDuration.value = 0
    currentVolumeLevel.value = 0

    console.log('✅ 强制停止录音完成')

    uni.showToast({
      title: '录音已停止',
      icon: 'success'
    })

  } catch (error) {
    console.error('❌ 强制停止录音失败:', error)

    // 即使出错也要重置状态
    recordingState.value = RecordingState.IDLE
    isRecording.value = false
    recordingPaused.value = false

    uni.showToast({
      title: '录音已强制停止',
      icon: 'none'
    })
  }
}

// 选择录音质量
function selectRecordingQuality() {
  // 先获取智能推荐
  const recommendation = getSmartQualityRecommendation()

  const qualityOptions = Object.entries(recordingConfig).map(([key, config]) => {
    let text = config.description
    if (key === recommendation.recommended) {
      text += ' (推荐)'
    }
    return { text, value: key }
  })

  // 添加智能推荐选项
  const itemList = ['🎯 查看智能推荐', ...qualityOptions.map(option => option.text)]

  uni.showActionSheet({
    itemList,
    success: (res) => {
      if (res.tapIndex === 0) {
        // 显示智能推荐
        showQualityRecommendation()
      } else {
        // 选择具体质量
        const selectedQuality = Object.keys(recordingConfig)[res.tapIndex - 1] as 'low' | 'medium' | 'high'

        if (selectedQuality !== recordingQuality.value) {
          recordingQuality.value = selectedQuality

          // 保存用户偏好
          try {
            uni.setStorageSync('recordingQuality', selectedQuality)
          } catch (error) {
            console.log('保存录音质量设置失败:', error)
          }

          const config = recordingConfig[selectedQuality]
          uni.showToast({
            title: `已选择${config.description}`,
            icon: 'none'
          })

          console.log('🎛️ 录音质量已更改为:', selectedQuality)
        }
      }
    },
    fail: (error) => {
      console.log('用户取消选择录音质量')
    }
  })
}

// 获取录音状态描述
function getRecordingStateDescription(state: RecordingState): string {
  switch (state) {
    case RecordingState.IDLE:
      return '待机'
    case RecordingState.PREPARING:
      return '准备中'
    case RecordingState.RECORDING:
      return '录音中'
    case RecordingState.PAUSED:
      return '已暂停'
    case RecordingState.STOPPING:
      return '停止中'
    case RecordingState.PROCESSING:
      return '处理中'
    case RecordingState.PREVIEW:
      return '预览中'
    case RecordingState.COMPLETED:
      return '已完成'
    case RecordingState.ERROR:
      return '错误'
    default:
      return '未知'
  }
}

// 获取录音时长格式化字符串
function getFormattedRecordingDuration(): string {
  const duration = recordingDuration.value
  const minutes = Math.floor(duration / 60)
  const seconds = duration % 60
  return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
}

// 开始音量监控
function startVolumeMonitoring() {
  if (volumeMonitorTimer.value) {
    clearInterval(volumeMonitorTimer.value)
  }

  // 重置音量历史
  volumeHistory.value = []
  currentVolumeLevel.value = 0

  // 启动模拟音量监控（因为微信小程序的frameBuffer可能不可用）
  volumeMonitorTimer.value = setInterval(() => {
    // 模拟音量变化（实际应用中应该从frameBuffer计算）
    const randomVolume = Math.floor(Math.random() * 20) + 1
    updateVolumeLevel(null, randomVolume)
  }, 100)

  console.log('🔊 音量监控已启动')
}

// 停止音量监控
function stopVolumeMonitoring() {
  if (volumeMonitorTimer.value) {
    clearInterval(volumeMonitorTimer.value)
    volumeMonitorTimer.value = null
  }

  currentVolumeLevel.value = 0
  console.log('🔇 音量监控已停止')
}

// 更新音量级别
function updateVolumeLevel(frameBuffer?: ArrayBuffer | null, mockVolume?: number) {
  let volumeLevel = 0

  if (mockVolume !== undefined) {
    // 使用模拟音量（用于演示）
    volumeLevel = mockVolume
  } else if (frameBuffer) {
    // 从音频帧数据计算音量
    try {
      const dataView = new DataView(frameBuffer)
      let sum = 0
      const length = dataView.byteLength / 2 // 16位音频

      for (let i = 0; i < length; i += 2) {
        const sample = dataView.getInt16(i * 2, true) // 小端序
        sum += Math.abs(sample)
      }

      const average = sum / length
      volumeLevel = Math.min(Math.floor((average / 32768) * 20), 20) // 转换为0-20级别
    } catch (error) {
      console.log('计算音量失败:', error)
      volumeLevel = Math.floor(Math.random() * 10) + 1 // 回退到随机值
    }
  }

  // 更新音量历史
  volumeHistory.value.push(volumeLevel)
  if (volumeHistory.value.length > maxVolumeHistory) {
    volumeHistory.value.shift()
  }

  // 平滑音量变化
  const smoothedVolume = volumeHistory.value.reduce((sum, vol) => sum + vol, 0) / volumeHistory.value.length
  currentVolumeLevel.value = Math.floor(smoothedVolume)
}

// 获取音量统计信息
function getVolumeStats() {
  if (volumeHistory.value.length === 0) {
    return { average: 0, max: 0, min: 0 }
  }

  const average = volumeHistory.value.reduce((sum, vol) => sum + vol, 0) / volumeHistory.value.length
  const max = Math.max(...volumeHistory.value)
  const min = Math.min(...volumeHistory.value)

  return { average: Math.round(average), max, min }
}

// 获取录音按钮标签
function getRecordingButtonLabel(): string {
  switch (recordingState.value) {
    case RecordingState.RECORDING:
      return supportsPauseResume.value ? '暂停' : '停止'
    case RecordingState.PAUSED:
      return '继续'
    case RecordingState.PREPARING:
      return '准备中'
    case RecordingState.STOPPING:
      return '停止中'
    case RecordingState.PROCESSING:
      return '处理中'
    default:
      return '录音'
  }
}

// 获取设备性能信息
async function getDevicePerformance() {
  try {
    // 获取系统信息
    const systemInfo = await uni.getSystemInfo()

    // 估算内存级别
    const totalMemory = systemInfo.memSize || 0
    let memoryLevel: 'low' | 'medium' | 'high' = 'medium'
    if (totalMemory < 3000) {
      memoryLevel = 'low'
    } else if (totalMemory > 6000) {
      memoryLevel = 'high'
    }

    // 获取存储信息
    let storageAvailable = 0
    try {
      if (typeof uni.getStorageInfo === 'function') {
        const storageInfo = await uni.getStorageInfo()
        if (storageInfo && storageInfo.limitSize && storageInfo.currentSize) {
          storageAvailable = storageInfo.limitSize - storageInfo.currentSize
        }
      }
    } catch (error) {
      console.log('获取存储信息失败:', error)
    }

    // 获取电池信息
    let batteryLevel = 100
    let isCharging = false
    try {
      if (typeof uni.getBatteryInfo === 'function') {
        const batteryInfo = await uni.getBatteryInfo()
        if (batteryInfo) {
          batteryLevel = batteryInfo.level || 100
          isCharging = batteryInfo.isCharging || false
        }
      }
    } catch (error) {
      console.log('获取电池信息失败:', error)
    }

    devicePerformance.value = {
      memoryLevel,
      storageAvailable,
      networkSpeed: 'unknown', // 需要通过网络测试获取
      batteryLevel,
      isCharging
    }

    console.log('📱 设备性能信息:', devicePerformance.value)

  } catch (error) {
    console.error('获取设备性能信息失败:', error)
  }
}

// 智能质量推荐
function getSmartQualityRecommendation() {
  const factors: string[] = []
  let score = 50 // 基础分数，50分对应medium质量

  // 存储空间因素
  const storageUsage = recordingStorageInfo.value.usagePercentage
  if (storageUsage > 80) {
    score -= 20
    factors.push('存储空间不足，建议使用低质量')
  } else if (storageUsage < 30) {
    score += 10
    factors.push('存储空间充足')
  }

  // 设备性能因素
  if (devicePerformance.value.memoryLevel === 'low') {
    score -= 15
    factors.push('设备内存较低')
  } else if (devicePerformance.value.memoryLevel === 'high') {
    score += 10
    factors.push('设备性能良好')
  }

  // 电池电量因素
  if (devicePerformance.value.batteryLevel < 20 && !devicePerformance.value.isCharging) {
    score -= 10
    factors.push('电池电量较低')
  } else if (devicePerformance.value.isCharging) {
    score += 5
    factors.push('设备正在充电')
  }

  // 网络状况因素（如果需要上传）
  if (recordingStorageConfig.backupToCloud) {
    if (devicePerformance.value.networkSpeed === 'slow') {
      score -= 10
      factors.push('网络速度较慢')
    } else if (devicePerformance.value.networkSpeed === 'fast') {
      score += 5
      factors.push('网络速度良好')
    }
  }

  // 历史使用偏好
  const savedQuality = uni.getStorageSync('recordingQuality')
  if (savedQuality) {
    factors.push(`用户偏好: ${recordingConfig[savedQuality as keyof typeof recordingConfig]?.description}`)
  }

  // 确定推荐质量
  let recommended: 'low' | 'medium' | 'high'
  let reason: string
  let confidence: number

  if (score < 30) {
    recommended = 'low'
    reason = '基于当前设备状况，推荐使用低质量以节省空间和电量'
    confidence = Math.max(100 - score, 60)
  } else if (score > 70) {
    recommended = 'high'
    reason = '设备状况良好，可以使用高质量获得更好的录音效果'
    confidence = Math.min(score, 90)
  } else {
    recommended = 'medium'
    reason = '推荐使用标准质量，在效果和资源消耗间取得平衡'
    confidence = 80 - Math.abs(score - 50)
  }

  const recommendation = {
    recommended,
    reason,
    confidence: Math.round(confidence),
    factors
  }

  qualityRecommendation.value = recommendation
  console.log('🎯 智能质量推荐:', recommendation)

  return recommendation
}

// 显示质量推荐
function showQualityRecommendation() {
  const recommendation = getSmartQualityRecommendation()

  const content = `${recommendation.reason}\n\n推荐质量: ${recordingConfig[recommendation.recommended].description}\n置信度: ${recommendation.confidence}%\n\n影响因素:\n${recommendation.factors.map(f => `• ${f}`).join('\n')}`

  uni.showModal({
    title: '智能质量推荐',
    content,
    confirmText: '使用推荐',
    cancelText: '手动选择',
    success: (res) => {
      if (res.confirm) {
        // 使用推荐质量
        recordingQuality.value = recommendation.recommended
        try {
          uni.setStorageSync('recordingQuality', recordingQuality.value)
        } catch (error) {
          console.log('保存录音质量设置失败:', error)
        }

        uni.showToast({
          title: `已设置为${recordingConfig[recommendation.recommended].description}`,
          icon: 'none'
        })
      } else {
        // 显示手动选择
        selectRecordingQuality()
      }
    }
  })
}

// 分析录音质量
function analyzeRecordingQuality(recordingData: any) {
  const { duration, fileSize, quality } = recordingData
  const config = recordingConfig[quality as keyof typeof recordingConfig]

  if (!config) return null

  // 计算压缩率
  const expectedSize = estimateRecordingSize(duration, quality)
  const compressionRatio = fileSize / expectedSize

  // 计算比特率
  const actualBitRate = (fileSize * 8) / duration // bits per second
  const expectedBitRate = config.encodeBitRate
  const bitRateRatio = actualBitRate / expectedBitRate

  // 质量评分
  let qualityScore = 100

  if (compressionRatio > 1.2) {
    qualityScore -= 10 // 文件过大
  } else if (compressionRatio < 0.8) {
    qualityScore -= 15 // 压缩过度
  }

  if (bitRateRatio < 0.8) {
    qualityScore -= 20 // 比特率过低
  } else if (bitRateRatio > 1.2) {
    qualityScore -= 5 // 比特率过高
  }

  // 时长因素
  if (duration < 5) {
    qualityScore -= 10 // 录音过短
  }

  const analysis = {
    qualityScore: Math.max(qualityScore, 0),
    compressionRatio: Math.round(compressionRatio * 100) / 100,
    actualBitRate: Math.round(actualBitRate),
    expectedBitRate,
    bitRateRatio: Math.round(bitRateRatio * 100) / 100,
    suggestions: [] as string[]
  }

  // 生成建议
  if (analysis.qualityScore < 70) {
    analysis.suggestions.push('录音质量较低，建议检查录音环境')
  }
  if (analysis.compressionRatio > 1.2) {
    analysis.suggestions.push('文件大小超出预期，可能存在冗余数据')
  }
  if (analysis.bitRateRatio < 0.8) {
    analysis.suggestions.push('比特率偏低，建议提高录音质量设置')
  }
  if (duration < 5) {
    analysis.suggestions.push('录音时间较短，建议录制更完整的内容')
  }

  console.log('📊 录音质量分析:', analysis)
  return analysis
}

// 估算录音文件大小
function estimateRecordingSize(durationSeconds: number, quality: 'low' | 'medium' | 'high'): number {
  const config = recordingConfig[quality]
  if (!config) return 0

  // 基于比特率估算
  const bitsPerSecond = config.encodeBitRate
  const bytesPerSecond = bitsPerSecond / 8
  const estimatedSize = bytesPerSecond * durationSeconds

  // 添加容器开销（约5%）
  return Math.round(estimatedSize * 1.05)
}

// 更新录音播放次数（录音存储管理功能已删除）
function updateRecordingPlayCount(recordingId: string) {
  // 录音存储管理功能已删除，不再统计播放次数
  console.log('📊 录音存储管理功能已删除，跳过播放次数统计')
}

// 获取用户录音的播放URL
function getUserRecordingPlayUrl(recording: any): string {
  // 如果录音已上传到云端，优先使用云端URL
  if (recording.uploaded && recording.cloudUrl) {
    return recording.cloudUrl
  }

  // 否则使用本地文件路径
  return recording.filePath
}

// 检查录音文件是否存在
async function checkRecordingFileExists(filePath: string): Promise<boolean> {
  try {
    await uni.getFileInfo({ filePath })
    return true
  } catch (error) {
    console.log('录音文件不存在:', filePath)
    return false
  }
}



// 添加到上传队列
function addToUploadQueue(recordingData: any) {
  const uploadItem = {
    id: recordingData.id,
    filePath: recordingData.filePath,
    bookId: recordingData.bookId,
    pageNumber: recordingData.pageNumber,
    priority: recordingData.isActive ? 10 : 5 // 活跃录音优先级更高
  }

  uploadQueue.value.push(uploadItem)
  console.log('📤 已添加到上传队列:', uploadItem.id)

  // 启动上传处理
  processUploadQueue()
}

// 处理上传队列
async function processUploadQueue() {
  if (isUploading.value || uploadQueue.value.length === 0) {
    return
  }

  isUploading.value = true

  try {
    // 按优先级排序
    uploadQueue.value.sort((a, b) => b.priority - a.priority)

    while (uploadQueue.value.length > 0) {
      const uploadItem = uploadQueue.value.shift()!

      if (uploadingRecordings.value.has(uploadItem.id)) {
        continue // 跳过正在上传的
      }

      try {
        await uploadRecordingToCloud(uploadItem)
      } catch (error) {
        console.error('上传录音失败:', uploadItem.id, error)

        // 重新加入队列（降低优先级）
        uploadItem.priority = Math.max(uploadItem.priority - 1, 1)
        uploadQueue.value.push(uploadItem)
      }

      // 避免过于频繁的上传
      await new Promise(resolve => setTimeout(resolve, 1000))
    }
  } finally {
    isUploading.value = false
  }
}

// 上传录音文件（调用API）
async function uploadRecordingFile(filePath: string, recordingData: any): Promise<{
  url: string,
  recordingId?: number,
  duration?: number,
  quality?: string,
  fileSize?: number
}> {
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: `${import.meta.env.VITE_SERVER_BASEURL}/app-api/reading/recordings/upload`,
      filePath: filePath,
      name: 'file',
      formData: (() => {
        const formData: any = {
          bookId: recordingData.bookId,
          duration: recordingData.duration,
          quality: recordingData.quality || 'medium'
        }

        // 只添加有效的页面参数
        if (recordingData.pageId !== undefined && recordingData.pageId !== null) {
          formData.pageId = recordingData.pageId
        } else if (recordingData.pageNumber !== undefined && recordingData.pageNumber !== null) {
          // 页面编号从0开始，但数据库中从1开始，所以+1
          formData.pageNumber = recordingData.pageNumber + 1
        }

        console.log('📤 上传参数:', formData)
        return formData
      })(),
      header: {
        'Authorization': `Bearer ${uni.getStorageSync('token') || ''}`,
        'Content-Type': 'multipart/form-data'
      },
      success: (res) => {
        try {
          console.log('📤 录音上传响应:', res)
          const result = JSON.parse(res.data)
          if (result.code === 0) {
            // 后端返回的数据结构：{ recordingId, audioUrl, duration, quality, fileSize, createTime, status, message }
            resolve({
              url: result.data.audioUrl,
              recordingId: result.data.recordingId,
              duration: result.data.duration,
              quality: result.data.quality,
              fileSize: result.data.fileSize
            })
          } else {
            reject(new Error(result.msg || '上传失败'))
          }
        } catch (error) {
          console.error('解析上传响应失败:', error, res)
          reject(new Error('解析上传结果失败'))
        }
      },
      fail: (error) => {
        reject(error)
      }
    })
  })
}



// 开始录音
async function startRecording() {
  try {
    console.log('🎤 准备开始录音...')

    // 检查录音管理器是否可用
    if (!recorderManager.value) {
      console.error('❌ 录音管理器未初始化')
      uni.showToast({
        title: '录音功能不可用',
        icon: 'none'
      })
      return
    }

    // 检查并解决音频冲突
    const canProceed = await resolveAudioConflict('record')
    if (!canProceed) {
      console.log('⚠️ 音频冲突无法解决，取消录音')
      return
    }

    // 检查录音权限
    console.log('🔍 检查录音权限...')
    const hasPermission = await checkRecordingPermission()

    if (!hasPermission) {
      console.log('❌ 录音权限检查失败')
      const currentStatus = recordingPermissionStatus.value

      if (currentStatus === 'denied' || currentStatus === 'temporarily_denied') {
        const reason = currentStatus === 'denied' ? '权限被拒绝' : '权限获取临时失败'
        showPermissionDeniedDialog(reason)
      } else {
        showPermissionDeniedDialog('无法获取录音权限')
      }
      return
    }

    console.log('✅ 录音权限检查通过')

    // 设置录音状态
    recordingState.value = RecordingState.PREPARING
    isRecording.value = true // 立即设置为true，确保覆盖层显示

    // 清除控制栏自动隐藏定时器，确保录音期间控制栏始终显示
    clearControlsAutoHideTimer()
    console.log('🎤 录音开始，已清除控制栏自动隐藏定时器')

    // 获取当前质量配置
    const config = recordingConfig[recordingQuality.value]

    // 录音配置
    const options = {
      duration: config.maxDuration,
      sampleRate: config.sampleRate,
      numberOfChannels: config.numberOfChannels,
      encodeBitRate: config.encodeBitRate,
      format: config.format
    }

    console.log('🎤 开始录音，质量:', recordingQuality.value, '配置:', options)
    console.log('🔍 录音管理器状态:', recorderManager.value ? '已初始化' : '未初始化')

    // 重置录音相关状态
    recordingDuration.value = 0
    recordingFilePath.value = ''
    recordingFileSize.value = 0
    recordingPaused.value = false

    console.log('🔍 准备调用 recorderManager.start()')
    recorderManager.value.start(options)
    console.log('✅ 已调用 recorderManager.start()，等待 onStart 事件')

    uni.showToast({
      title: '开始录制配音',
      icon: 'none'
    })
  } catch (error) {
    console.error('❌ 开始录音失败:', error)
    isRecording.value = false

    // 根据错误类型显示不同提示
    let errorMessage = '录音启动失败'
    if (error && typeof error === 'object' && 'errMsg' in error) {
      if (error.errMsg.includes('permission')) {
        errorMessage = '录音权限不足'
        recordingPermissionStatus.value = 'denied'
        setTimeout(() => {
          showPermissionDeniedDialog('录音权限不足')
        }, 1000)
      } else if (error.errMsg.includes('busy')) {
        errorMessage = '录音设备忙碌'
      }
    }

    uni.showToast({
      title: errorMessage,
      icon: 'none'
    })
  }
}

// 暂停录音
function pauseRecording() {
  try {
    if (recordingState.value !== RecordingState.RECORDING) {
      console.log('⚠️ 当前状态不允许暂停录音:', recordingState.value)
      return
    }

    // 检查是否支持暂停功能
    if (!recorderManager.value || typeof recorderManager.value.pause !== 'function') {
      console.log('⚠️ 当前平台不支持录音暂停功能')
      uni.showToast({
        title: '当前平台不支持暂停录音',
        icon: 'none'
      })
      return
    }

    console.log('⏸️ 暂停录音')
    recorderManager.value.pause()
  } catch (error) {
    console.error('❌ 暂停录音失败:', error)
    uni.showToast({
      title: '暂停录音失败',
      icon: 'none'
    })
  }
}

// 恢复录音
function resumeRecording() {
  try {
    if (recordingState.value !== RecordingState.PAUSED) {
      console.log('⚠️ 当前状态不允许恢复录音:', recordingState.value)
      return
    }

    // 检查是否支持恢复功能
    if (!recorderManager.value || typeof recorderManager.value.resume !== 'function') {
      console.log('⚠️ 当前平台不支持录音恢复功能')
      uni.showToast({
        title: '当前平台不支持恢复录音',
        icon: 'none'
      })
      return
    }

    console.log('▶️ 恢复录音')
    recorderManager.value.resume()
  } catch (error) {
    console.error('❌ 恢复录音失败:', error)
    uni.showToast({
      title: '恢复录音失败',
      icon: 'none'
    })
  }
}

// 停止录音
function stopRecording() {
  try {
    console.log('🔍 停止录音被调用，当前状态:', recordingState.value)

    if (recordingState.value === RecordingState.IDLE || recordingState.value === RecordingState.COMPLETED) {
      console.log('⚠️ 当前状态不允许停止录音:', recordingState.value)
      return
    }

    if (!recorderManager.value) {
      console.error('❌ 录音管理器不存在')
      return
    }

    console.log('⏹️ 停止录音')
    recordingState.value = RecordingState.STOPPING

    // 检查stop方法是否存在
    if (typeof recorderManager.value.stop === 'function') {
      console.log('🔍 准备调用录音管理器的stop方法')
      recorderManager.value.stop()
      console.log('✅ 已调用录音管理器的stop方法，等待onStop事件')
    } else {
      console.error('❌ 录音管理器没有stop方法')
      throw new Error('录音管理器没有stop方法')
    }

    uni.showToast({
      title: '录音结束，正在处理...',
      icon: 'none'
    })
  } catch (error) {
    console.error('❌ 停止录音失败:', error)
    recordingState.value = RecordingState.ERROR
    isRecording.value = false
    recordingPaused.value = false

    uni.showToast({
      title: '停止录音失败',
      icon: 'none'
    })
  }
}



// 获取当前页面的用户录音（优先返回服务器端录音，其次返回临时录音）
const getCurrentPageUserRecording = (): any | null => {
  // 优先返回服务器端录音
  if (serverUserRecording.value) {
    return {
      id: serverUserRecording.value.id,
      filePath: serverUserRecording.value.audioUrl,
      duration: serverUserRecording.value.duration,
      quality: serverUserRecording.value.recordingQuality || 'medium'
    }
  }

  // 其次返回临时录音
  if (currentPageRecording.value &&
      currentPageRecording.value.bookId === Number(bookId.value) &&
      currentPageRecording.value.pageNumber === currentPage.value) {
    return currentPageRecording.value
  }
  return null
}

// 返回上一页
const goBack = async () => {
  try {
    console.log('🔙 用户点击返回按钮')

    // 重置控制栏自动隐藏定时器
    resetControlsAutoHideTimer()

    // 立即停止音频播放并暂停自动播放
    stopAudioPlayback('用户退出页面', true) // 标记为用户操作，暂停自动播放

    // 清理所有定时器
    if (autoTurnTimer) {
      clearTimeout(autoTurnTimer)
      autoTurnTimer = null
    }

    // 先保存最终阅读记录，确保数据同步
    if (bookId.value && pageStartTime.value > 0) {
      console.log('返回前保存最终阅读记录')
      await saveFinalReadingRecord()
    }

    // 如果是横屏模式，先切换到竖屏
    if (isLandscape.value) {
      try {
        // uni.setScreenOrientation({
        //   orientation: 'portrait'
        // })
      } catch (error) {
        console.log('恢复屏幕方向失败:', error)
      }
    }

    // 等待保存完成后再返回
    uni.navigateBack()
  } catch (error) {
    console.error('返回时保存阅读记录失败:', error)
    // 即使保存失败也要返回，避免用户被困在页面
    uni.navigateBack()
  }
}

// 图片加载事件
function onImageLoad(event: any) {
  console.log('图片加载成功')

  // 获取图片的实际尺寸
  if (event && event.detail) {
    const { width, height } = event.detail

    // 更新图片信息
    imageInfo.value = {
      width,
      height,
      aspectRatio: width / height
    }

    // 根据图片长宽比判断图片类型
    // 宽度大于高度为横式图片，否则为竖式图片
    const detectedImageType = width > height ? 'landscape' : 'portrait'
    currentImageType.value = detectedImageType

    console.log('📸 图片尺寸检测:', {
      width,
      height,
      aspectRatio: imageInfo.value.aspectRatio,
      imageType: detectedImageType
    })

    // 根据图片类型自动调整显示方向（可选）
    // imageOrientation.value = detectedImageType
  }
}

function onImageError() {
  console.log('图片加载失败')
}

// 重录当前页面
const reRecord = async () => {
  try {
    // 检查是否有现有录音
    const existingRecording = getCurrentPageUserRecording()

    if (existingRecording) {
      // 如果有现有录音，询问是否覆盖
      uni.showModal({
        title: '重新录制',
        content: '当前页面已有录音，重新录制将覆盖现有录音。是否继续？',
        confirmText: '继续录制',
        cancelText: '取消',
        success: (res) => {
          if (res.confirm) {
            // 清除现有临时录音
            currentPageRecording.value = null
            // 开始录制
            startRecording()
          }
        }
      })
    } else {
      // 没有现有录音，直接开始录制
      await startRecording()
    }
  } catch (error) {
    console.error('重录失败:', error)
    uni.showToast({
      title: '重录失败',
      icon: 'none'
    })
  }
}



// 分享录音功能已删除

// 处理覆盖层点击
function handleOverlayClick() {
  console.log('🚨 覆盖层背景被点击，停止录音')

  // 调试：检查覆盖层状态
  debugOverlayState()

  // 强制刷新覆盖层状态
  forceRefreshOverlay()

  handleOverlayStopClick()
}

// 调试函数：检查覆盖层状态
function debugOverlayState() {
  try {
    console.log('🔍 覆盖层状态调试:')
    console.log('  - isRecording:', isRecording.value)
    console.log('  - recordingState:', recordingState.value)
    console.log('  - 覆盖层显示条件:',
      isRecording.value ||
      recordingState.value === RecordingState.RECORDING ||
      recordingState.value === RecordingState.PAUSED ||
      recordingState.value === RecordingState.PREPARING
    )
    console.log('  - 当前时间戳:', Date.now())
  } catch (error) {
    console.error('调试覆盖层失败:', error)
  }
}

// 处理覆盖层停止按钮点击
function handleOverlayStopClick() {
  console.log('⏹️ 覆盖层停止按钮被点击')

  try {
    stopRecording()
  } catch (error) {
    console.error('❌ 覆盖层停止录音失败:', error)
    // 如果正常停止失败，尝试强制停止
    forceStopRecording()
  }
}























// 错误处理和用户反馈系统

// 记录错误
function logError(type: ErrorType, message: string, details?: any, userAction?: string) {
  const errorId = `error_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`

  const errorRecord = {
    id: errorId,
    type,
    message,
    details: details || {},
    timestamp: new Date().toISOString(),
    resolved: false,
    userAction
  }

  errorHistory.value.unshift(errorRecord)

  // 限制错误历史记录数量
  if (errorHistory.value.length > maxErrorHistory) {
    errorHistory.value = errorHistory.value.slice(0, maxErrorHistory)
  }

  console.error(`[${type}] ${message}`, details)

  // 保存到本地存储（用于调试）
  try {
    const recentErrors = errorHistory.value.slice(0, 10) // 只保存最近10个错误
    uni.setStorageSync('recentErrors', recentErrors)
  } catch (error) {
    console.log('保存错误记录失败:', error)
  }

  return errorId
}

// 显示用户友好的错误提示
function showUserFriendlyError(type: ErrorType, originalMessage: string, details?: any) {
  let userMessage = ''
  let suggestions: string[] = []
  let actions: Array<{ text: string, action: () => void }> = []

  switch (type) {
    case ErrorType.PERMISSION_DENIED:
      userMessage = '需要相关权限才能使用此功能'
      suggestions = [
        '请在设置中开启相关权限',
        '重启应用后重试'
      ]
      actions = [
        {
          text: '去设置',
          action: () => {
            uni.openSetting({
              success: (res) => {
                console.log('用户设置结果:', res.authSetting)
              }
            })
          }
        }
      ]
      break

    case ErrorType.NETWORK_ERROR:
      userMessage = '网络连接异常'
      suggestions = [
        '请检查网络连接',
        '稍后重试',
        '切换网络环境'
      ]
      actions = [
        {
          text: '重试',
          action: () => {
            // 重试逻辑由调用方提供
            console.log('用户选择重试')
          }
        }
      ]
      break

    case ErrorType.STORAGE_ERROR:
      userMessage = '存储空间不足或存储异常'
      suggestions = [
        '清理设备存储空间',
        '清理应用缓存',
        '重启应用'
      ]
      actions = [
        {
          text: '清理缓存',
          action: () => {
            clearAllRecordings()
          }
        }
      ]
      break

    case ErrorType.AUDIO_ERROR:
      userMessage = '音频播放异常'
      suggestions = [
        '检查音频文件是否完整',
        '重启应用',
        '检查设备音频设置'
      ]
      break

    case ErrorType.RECORDING_ERROR:
      userMessage = '录音功能异常'
      suggestions = [
        '检查录音权限',
        '检查设备麦克风',
        '重启应用'
      ]
      actions = [
        {
          text: '检查权限',
          action: () => {
            checkRecordingPermission()
          }
        }
      ]
      break

    case ErrorType.FILE_ERROR:
      userMessage = '文件操作失败'
      suggestions = [
        '检查存储空间',
        '重试操作',
        '重启应用'
      ]
      break

    case ErrorType.SYSTEM_ERROR:
      userMessage = '系统异常'
      suggestions = [
        '重启应用',
        '更新应用版本',
        '联系技术支持'
      ]
      break

    case ErrorType.USER_ERROR:
      userMessage = originalMessage // 用户错误直接显示原始消息
      break

    default:
      userMessage = '操作失败，请重试'
      suggestions = ['重试操作', '重启应用']
  }

  // 记录错误
  const errorId = logError(type, originalMessage, details)

  // 显示错误反馈
  showFeedback('error', userMessage, suggestions.join('\n'), 5000, actions)

  return errorId
}

// 显示反馈信息
function showFeedback(
  type: 'success' | 'warning' | 'error' | 'info',
  title: string,
  message: string,
  duration: number = 3000,
  actions?: Array<{ text: string, action: () => void }>
) {
  const feedbackId = `feedback_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`

  const feedback = {
    id: feedbackId,
    type,
    title,
    message,
    duration,
    actions
  }

  feedbackQueue.value.push(feedback)

  // 如果当前没有显示反馈，立即显示
  if (!currentFeedback.value) {
    showNextFeedback()
  }

  return feedbackId
}

// 显示下一个反馈
function showNextFeedback() {
  if (feedbackQueue.value.length === 0) {
    currentFeedback.value = null
    return
  }

  const feedback = feedbackQueue.value.shift()!
  currentFeedback.value = feedback

  // 根据类型选择显示方式
  if (feedback.actions && feedback.actions.length > 0) {
    // 有操作按钮，使用模态框
    const actionTexts = feedback.actions.map(action => action.text)

    uni.showModal({
      title: feedback.title,
      content: feedback.message,
      showCancel: actionTexts.length > 1,
      confirmText: actionTexts[0] || '确定',
      cancelText: actionTexts[1] || '取消',
      success: (res) => {
        if (res.confirm && feedback.actions![0]) {
          feedback.actions![0].action()
        } else if (res.cancel && feedback.actions![1]) {
          feedback.actions![1].action()
        }

        // 显示下一个反馈
        setTimeout(() => {
          showNextFeedback()
        }, 500)
      }
    })
  } else {
    // 无操作按钮，使用Toast
    const icon = feedback.type === 'success' ? 'success' :
                 feedback.type === 'error' ? 'error' : 'none'

    uni.showToast({
      title: feedback.title,
      icon,
      duration: feedback.duration
    })

    // 显示下一个反馈
    setTimeout(() => {
      showNextFeedback()
    }, feedback.duration)
  }
}

// 处理录音相关错误
function handleRecordingError(error: any, operation: string) {
  let errorType = ErrorType.RECORDING_ERROR
  let message = `录音${operation}失败`

  if (error && error.errMsg) {
    if (error.errMsg.includes('permission')) {
      errorType = ErrorType.PERMISSION_DENIED
      message = '录音权限被拒绝'
    } else if (error.errMsg.includes('busy')) {
      message = '录音设备忙碌'
    } else if (error.errMsg.includes('timeout')) {
      message = '录音超时'
    } else if (error.errMsg.includes('interrupted')) {
      message = '录音被中断'
    }
  }

  return showUserFriendlyError(errorType, message, { operation, originalError: error })
}

// 处理音频播放错误
function handleAudioError(error: any, operation: string) {
  let errorType = ErrorType.AUDIO_ERROR
  let message = `音频${operation}失败`

  if (error && error.errMsg) {
    if (error.errMsg.includes('network')) {
      errorType = ErrorType.NETWORK_ERROR
      message = '音频加载失败，请检查网络连接'
    } else if (error.errMsg.includes('format')) {
      message = '音频格式不支持'
    } else if (error.errMsg.includes('decode')) {
      message = '音频解码失败'
    }
  }

  return showUserFriendlyError(errorType, message, { operation, originalError: error })
}

// 处理文件操作错误
function handleFileError(error: any, operation: string, filePath?: string) {
  let errorType = ErrorType.FILE_ERROR
  let message = `文件${operation}失败`

  if (error && error.errMsg) {
    if (error.errMsg.includes('not found')) {
      message = '文件不存在'
    } else if (error.errMsg.includes('permission')) {
      errorType = ErrorType.PERMISSION_DENIED
      message = '文件访问权限不足'
    } else if (error.errMsg.includes('space')) {
      errorType = ErrorType.STORAGE_ERROR
      message = '存储空间不足'
    }
  }

  return showUserFriendlyError(errorType, message, { operation, filePath, originalError: error })
}

// 处理网络错误
function handleNetworkError(error: any, operation: string) {
  let message = `网络${operation}失败`

  if (error && error.errMsg) {
    if (error.errMsg.includes('timeout')) {
      message = '网络请求超时'
    } else if (error.errMsg.includes('abort')) {
      message = '网络请求被取消'
    } else if (error.errMsg.includes('offline')) {
      message = '网络连接不可用'
    }
  }

  return showUserFriendlyError(ErrorType.NETWORK_ERROR, message, { operation, originalError: error })
}

// 获取错误统计
function getErrorStatistics() {
  const stats = {
    total: errorHistory.value.length,
    byType: {} as Record<string, number>,
    recent: errorHistory.value.slice(0, 5),
    resolved: errorHistory.value.filter(e => e.resolved).length
  }

  errorHistory.value.forEach(error => {
    stats.byType[error.type] = (stats.byType[error.type] || 0) + 1
  })

  return stats
}

// 标记错误为已解决
function markErrorAsResolved(errorId: string) {
  const error = errorHistory.value.find(e => e.id === errorId)
  if (error) {
    error.resolved = true
    console.log('错误已标记为解决:', errorId)
  }
}

// 清理错误历史
function clearErrorHistory() {
  errorHistory.value = []
  try {
    uni.removeStorageSync('recentErrors')
  } catch (error) {
    console.log('清理错误记录失败:', error)
  }
}

// 性能优化和监控系统

// 启动性能监控
function startPerformanceMonitoring() {
  if (!performanceConfig.monitoringEnabled) {
    return
  }

  console.log('📊 启动性能监控')

  // 定期采样性能指标
  performanceMonitorTimer.value = setInterval(() => {
    collectPerformanceMetrics()
  }, performanceConfig.sampleInterval)

  // 启动电池监控
  startBatteryMonitoring()
}

// 收集性能指标
async function collectPerformanceMetrics() {
  try {
    const startTime = Date.now()

    // 获取内存信息
    let memoryUsage = 0
    try {
      // 检查是否支持 getMemoryInfo API
      if (typeof uni.getMemoryInfo === 'function') {
        const memoryInfo = await uni.getMemoryInfo()
        if (memoryInfo && memoryInfo.usedJSHeapSize && memoryInfo.totalJSHeapSize) {
          memoryUsage = (memoryInfo.usedJSHeapSize / memoryInfo.totalJSHeapSize) * 100
        }
      } else {
        // 使用浏览器的 performance.memory API 作为备选
        if (typeof window !== 'undefined' && window.performance && (window.performance as any).memory) {
          const memory = (window.performance as any).memory
          memoryUsage = (memory.usedJSHeapSize / memory.totalJSHeapSize) * 100
        }
      }
    } catch (error) {
      console.log('获取内存信息失败:', error)
    }

    // 获取电池信息
    let batteryLevel = 100
    try {
      // 检查是否支持 getBatteryInfo API
      if (typeof uni.getBatteryInfo === 'function') {
        const batteryInfo = await uni.getBatteryInfo()
        if (batteryInfo && typeof batteryInfo.level === 'number') {
          batteryLevel = batteryInfo.level
        }
      }
    } catch (error) {
      console.log('获取电池信息失败:', error)
    }

    // 计算网络延迟（简化版）
    const networkLatency = await measureNetworkLatency()

    // 更新性能指标
    performanceMetrics.value = {
      ...performanceMetrics.value,
      memoryUsage,
      networkLatency,
      storageIOTime: Date.now() - startTime
    }

    // 记录性能历史
    recordPerformanceHistory('monitoring', performanceMetrics.value)

    // 检查性能警告
    checkPerformanceAlerts()

  } catch (error) {
    console.error('收集性能指标失败:', error)
  }
}

// 测量网络延迟
async function measureNetworkLatency(): Promise<number> {
  const startTime = Date.now()

  try {
    // 发送一个简单的网络请求来测量延迟
    await uni.request({
      url: `${import.meta.env.VITE_SERVER_BASEURL}/health`,
      method: 'GET',
      timeout: 5000
    })

    return Date.now() - startTime
  } catch (error) {
    return -1 // 网络不可用
  }
}

// 记录性能历史
function recordPerformanceHistory(operation: string, metrics: typeof performanceMetrics.value) {
  const record = {
    timestamp: new Date().toISOString(),
    metrics: { ...metrics },
    operation
  }

  performanceHistory.value.unshift(record)

  // 限制历史记录数量
  if (performanceHistory.value.length > performanceConfig.maxHistorySize) {
    performanceHistory.value = performanceHistory.value.slice(0, performanceConfig.maxHistorySize)
  }
}

// 检查性能警告
function checkPerformanceAlerts() {
  const metrics = performanceMetrics.value
  const thresholds = performanceConfig.alertThresholds

  // 内存使用率警告
  if (metrics.memoryUsage > thresholds.memoryUsage) {
    console.warn('⚠️ 内存使用率过高:', metrics.memoryUsage + '%')
    showFeedback('warning', '内存使用率较高', '建议关闭其他应用或重启应用', 3000)

    // 触发内存优化
    optimizeMemoryUsage()
  }

  // 录音延迟警告
  if (metrics.recordingLatency > thresholds.recordingLatency) {
    console.warn('⚠️ 录音延迟过高:', metrics.recordingLatency + 'ms')
    showFeedback('warning', '录音响应较慢', '建议重启应用或检查设备性能', 3000)
  }

  // 音频加载时间警告
  if (metrics.audioLoadTime > thresholds.audioLoadTime) {
    console.warn('⚠️ 音频加载时间过长:', metrics.audioLoadTime + 'ms')
    showFeedback('warning', '音频加载较慢', '建议检查网络连接', 3000)
  }
}

// 启动电池监控
function startBatteryMonitoring() {
  batteryMonitorTimer.value = setInterval(async () => {
    try {
      if (typeof uni.getBatteryInfo === 'function') {
        const batteryInfo = await uni.getBatteryInfo()
        if (batteryInfo) {
          const currentLevel = batteryInfo.level || 100
          const isCharging = batteryInfo.isCharging || false

          // 更新设备性能信息
          devicePerformance.value.batteryLevel = currentLevel
          devicePerformance.value.isCharging = isCharging

          // 检查低电量模式
          if (currentLevel < 20 && !isCharging) {
            enableLowPowerMode()
          } else if (currentLevel > 30 || isCharging) {
            disableLowPowerMode()
          }
        }
      }
    } catch (error) {
      console.log('电池监控失败:', error)
    }
  }, 30000) // 每30秒检查一次电池状态
}

// 启用低电量模式
function enableLowPowerMode() {
  if (batteryOptimization.value.lowPowerMode) {
    return // 已经启用
  }

  console.log('🔋 启用低电量模式')
  batteryOptimization.value.lowPowerMode = true

  // 降低录音质量
  if (batteryOptimization.value.qualityAdjustment) {
    if (recordingQuality.value === 'high') {
      recordingQuality.value = 'medium'
      showFeedback('info', '已切换到标准录音质量', '为节省电量', 2000)
    } else if (recordingQuality.value === 'medium') {
      recordingQuality.value = 'low'
      showFeedback('info', '已切换到低录音质量', '为节省电量', 2000)
    }
  }

  // 减少性能监控频率
  if (performanceMonitorTimer.value) {
    clearInterval(performanceMonitorTimer.value)
    performanceMonitorTimer.value = setInterval(() => {
      collectPerformanceMetrics()
    }, performanceConfig.sampleInterval * 2) // 频率减半
  }

  // 禁用音量监控
  stopVolumeMonitoring()
}

// 禁用低电量模式
function disableLowPowerMode() {
  if (!batteryOptimization.value.lowPowerMode) {
    return // 已经禁用
  }

  console.log('🔋 禁用低电量模式')
  batteryOptimization.value.lowPowerMode = false

  // 恢复正常性能监控频率
  if (performanceMonitorTimer.value) {
    clearInterval(performanceMonitorTimer.value)
    performanceMonitorTimer.value = setInterval(() => {
      collectPerformanceMetrics()
    }, performanceConfig.sampleInterval)
  }

  showFeedback('info', '已退出低电量模式', '性能已恢复正常', 2000)
}

// 内存优化
function optimizeMemoryUsage() {
  console.log('🧹 开始内存优化')

  try {
    // 清理音频缓存
    if (audioCache.size > 5) {
      const keysToDelete = Array.from(audioCache.keys()).slice(5)
      keysToDelete.forEach(key => audioCache.delete(key))
      console.log('清理音频缓存:', keysToDelete.length, '项')
    }

    // 清理翻译缓存
    try {
      const translations = uni.getStorageSync('translations') || {}
      const translationKeys = Object.keys(translations)
      if (translationKeys.length > 50) {
        const keysToDelete = translationKeys.slice(50)
        keysToDelete.forEach(key => delete translations[key])
        uni.setStorageSync('translations', translations)
        console.log('清理翻译缓存:', keysToDelete.length, '项')
      }
    } catch (error) {
      console.log('清理翻译缓存失败:', error)
    }

    // 清理错误历史
    if (errorHistory.value.length > 20) {
      errorHistory.value = errorHistory.value.slice(0, 20)
      console.log('清理错误历史')
    }

    // 清理性能历史
    if (performanceHistory.value.length > 50) {
      performanceHistory.value = performanceHistory.value.slice(0, 50)
      console.log('清理性能历史')
    }

    // 强制垃圾回收（如果支持）
    if (typeof window !== 'undefined' && (window as any).gc) {
      (window as any).gc()
      console.log('执行垃圾回收')
    }

    showFeedback('success', '内存优化完成', '已清理缓存数据', 2000)

  } catch (error) {
    console.error('内存优化失败:', error)
  }
}

// 测量录音延迟
function measureRecordingLatency(): Promise<number> {
  return new Promise((resolve) => {
    const startTime = Date.now()

    // 模拟录音启动延迟测量
    const testRecorder = uni.getRecorderManager()

    testRecorder.onStart(() => {
      const latency = Date.now() - startTime
      performanceMetrics.value.recordingLatency = latency
      testRecorder.stop()
      resolve(latency)
    })

    testRecorder.onError(() => {
      resolve(-1) // 测量失败
    })

    // 启动测试录音
    testRecorder.start({
      duration: 100, // 很短的录音
      sampleRate: 8000,
      numberOfChannels: 1,
      encodeBitRate: 32000,
      format: 'mp3'
    })

    // 超时保护
    setTimeout(() => {
      testRecorder.stop()
      resolve(-1)
    }, 5000)
  })
}

// 测量音频加载时间
function measureAudioLoadTime(audioUrl: string): Promise<number> {
  return new Promise((resolve) => {
    const startTime = Date.now()
    const testAudio = uni.createInnerAudioContext()

    testAudio.onCanplay(() => {
      const loadTime = Date.now() - startTime
      performanceMetrics.value.audioLoadTime = loadTime
      testAudio.destroy()
      resolve(loadTime)
    })

    testAudio.onError(() => {
      testAudio.destroy()
      resolve(-1) // 加载失败
    })

    testAudio.src = audioUrl

    // 超时保护
    setTimeout(() => {
      testAudio.destroy()
      resolve(-1)
    }, 10000)
  })
}

// 获取性能报告
function getPerformanceReport() {
  const currentMetrics = performanceMetrics.value
  const recentHistory = performanceHistory.value.slice(0, 10)

  // 计算平均值
  const avgMetrics = {
    memoryUsage: 0,
    networkLatency: 0,
    recordingLatency: 0,
    audioLoadTime: 0
  }

  if (recentHistory.length > 0) {
    recentHistory.forEach(record => {
      avgMetrics.memoryUsage += record.metrics.memoryUsage
      avgMetrics.networkLatency += record.metrics.networkLatency
      avgMetrics.recordingLatency += record.metrics.recordingLatency
      avgMetrics.audioLoadTime += record.metrics.audioLoadTime
    })

    Object.keys(avgMetrics).forEach(key => {
      avgMetrics[key as keyof typeof avgMetrics] /= recentHistory.length
    })
  }

  return {
    current: currentMetrics,
    average: avgMetrics,
    history: recentHistory,
    deviceInfo: devicePerformance.value,
    batteryOptimization: batteryOptimization.value,
    recommendations: generatePerformanceRecommendations()
  }
}

// 生成性能建议
function generatePerformanceRecommendations(): string[] {
  const recommendations: string[] = []
  const metrics = performanceMetrics.value
  const device = devicePerformance.value

  if (metrics.memoryUsage > 70) {
    recommendations.push('内存使用率较高，建议关闭其他应用')
  }

  if (device.batteryLevel < 30 && !device.isCharging) {
    recommendations.push('电池电量较低，建议连接充电器')
  }

  if (metrics.networkLatency > 2000) {
    recommendations.push('网络延迟较高，建议检查网络连接')
  }

  if (device.memoryLevel === 'low') {
    recommendations.push('设备内存较低，建议使用低质量录音')
  }

  // 录音存储管理功能已删除，跳过存储空间检查

  return recommendations
}
</script>

<style lang="scss" scoped>
// 导入公共样式变量
@import '@/styles/variables.scss';

.picture-book-reader {
  width: 100vw;
  height: 100vh;
  background-color: $black;
  overflow: hidden;

  &.landscape {
    .custom-navbar {
      display: none;
    }

    // 横屏模式下的特殊样式
    .book-content {
      height: 100vh !important;
    }

    .page-container {
      padding: 4px !important;
    }
  }
}

/* 自定义导航栏 - 儿童友好风格 */
.custom-navbar {
  @include glass-effect(0.95);
  border-bottom: 1px solid $border-color-light;
  position: relative;
  z-index: $z-index-sticky;
  backdrop-filter: $glass-blur;

  .navbar-content {
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 $spacing-xl;

    .navbar-left {
      display: flex;
      align-items: center;
      cursor: pointer;
      padding: $spacing-sm;
      border-radius: $border-radius-md;
      transition: $transition-all;

      &:active {
        background-color: $light-gray;
        transform: scale(0.95);
      }

      .back-text {
        margin-left: $spacing-sm;
        font-size: $font-size-md;
        color: $dark-gray;
        font-family: $font-family;
        font-weight: $font-weight-medium;
      }
    }
    
    .navbar-title {
      flex: 1;
      text-align: center;

      .title-text {
        font-size: $font-size-lg;
        font-weight: $font-weight-semibold;
        color: $dark-gray;
        font-family: $font-family;
      }
    }

    .navbar-right {
      cursor: pointer;
      padding: $spacing-sm;
      border-radius: $border-radius-md;
      transition: $transition-all;

      &:active {
        background-color: $light-gray;
        transform: scale(0.95);
      }


    }
  }
}

/* 绘本内容区域 */
.book-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  height: calc(100vh - 44px);

  &.fullscreen {
    height: 100vh;
  }

  &.no-navbar {
    height: 100vh;
  }
}

/* 图片轮播 */
.book-swiper {
  flex: 1;
  width: 100%;
  
  .page-container {
    width: 100%;
    height: 100%;
    position: relative;
    padding: 0;
    box-sizing: border-box;
    overflow: hidden;

    .book-page {
      border-radius: 0;
      transition: all 0.3s ease;
      transform-origin: center center;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      object-fit: contain;

      // 竖屏显示模式
      &.image-portrait {
        transform: translate(-50%, -50%) rotate(0deg);

        // 横式图片在竖屏模式下显示
        &.horizontal-image {
          width: 100vw;
          height: 56.25vw; // 16:9 比例
          max-height: 100vh;
        }

        // 竖式图片在竖屏模式下显示 - 全屏显示
        &.vertical-image {
          width: 100vw;
          height: 100vh;
        }
      }

      // 横屏显示模式 - 顺时针旋转90度
      &.image-landscape {
        transform: translate(-50%, -50%) rotate(90deg);

        // 横式图片在横屏模式下显示
        &.horizontal-image {
          width: 100vh;
          height: 56.25vh; // 保持16:9比例
          max-height: 100vw;
        }

        // 竖式图片在横屏模式下显示
        &.vertical-image {
          width: 75vh; // 适当调整
          height: 100vw;
          max-width: 100vh;
        }
      }
    }

    .loading {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: rgba(0, 0, 0, 0.7);
      color: #fff;
      padding: 10px 20px;
      border-radius: 6px;
      font-size: 14px;
    }
  }
}

/* 竖屏控制栏 - 儿童友好风格 */
.page-controls {
  background: rgba(0, 0, 0, 0.8);
  backdrop-filter: $glass-blur;
  padding: $spacing-md $spacing-xl;
  display: flex;
  justify-content: space-between;
  align-items: center;

  .page-info {
    .page-text {
      color: $white;
      font-size: $font-size-md;
      font-family: $font-family;
      font-weight: $font-weight-medium;
    }
  }

  .control-buttons {
    display: flex;
    gap: $spacing-md;

    .control-btn {
      background: $blue-gradient;
      color: $white;
      border: none;
      border-radius: $border-radius-md;
      padding: $spacing-sm $spacing-lg;
      font-size: $font-size-base;
      font-family: $font-family;
      font-weight: $font-weight-medium;
      box-shadow: $shadow-blue;
      transition: $transition-all;
      cursor: pointer;

      &:disabled {
        background: $medium-gray;
        opacity: 0.5;
        cursor: not-allowed;
      }

      &:not(:disabled):active {
        transform: scale(0.95);
        box-shadow: $shadow-blue-lg;
      }
    }
  }
}

/* 横屏控制栏 */
.landscape-controls {
  position: absolute;
  top: 50px;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  z-index: 100;

  // 左上角控制区
  .top-left-controls {
    position: absolute;
    top: 20px;
    left: 20px;
    display: flex;
    align-items: center;
    gap: 15px;
    pointer-events: auto;

    .book-info {
      background-color: rgba(0, 0, 0, 0.8);
      padding: 8px 15px;
      border-radius: 20px;

      .page-info {
        display: block;
        color: #fff;
        font-size: 16px;
        font-weight: 600;
        margin-bottom: 2px;
      }

      .book-title-small {
        display: block;
        color: rgba(255, 255, 255, 0.8);
        font-size: 12px;
        max-width: 150px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }
  }

  // 右上角控制区
  .top-right-controls {
    position: absolute;
    top: 20px;
    right: 20px;
    display: flex;
    gap: 10px;
    pointer-events: auto;
  }

  // 左侧中央控制区
  .left-center-controls {
    position: absolute;
    left: 20px;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    flex-direction: column;
    gap: 15px;
    pointer-events: auto;
  }

  // 右侧中央控制区
  .right-center-controls {
    position: absolute;
    right: 20px;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    flex-direction: column;
    gap: 15px;
    pointer-events: auto;
  }

  // 通用控制按钮样式 - 儿童友好风格
  .control-btn {
    width: 48px;
    height: 48px;
    background: rgba(0, 0, 0, 0.8);
    backdrop-filter: $glass-blur;
    border-radius: $border-radius-full;
    @include center-flex;
    color: $white;
    font-size: $font-size-md;
    font-weight: $font-weight-bold;
    font-family: $font-family;
    box-shadow: $shadow-lg;
    transition: $transition-all;
    cursor: pointer;

    &:active {
      transform: scale(0.9);
      background: rgba(0, 0, 0, 0.9);
    }

    &.active {
      background: rgba(0, 122, 255, 0.9);
      color: $white;
      box-shadow: 0 0 20px rgba(0, 122, 255, 0.5);
    }

    &.disabled {
      // background: rgba(128, 128, 128, 0.6);
      color: rgba(255, 255, 255, 0.5);
      cursor: not-allowed;

      &:active {
        transform: none;
        background: rgba(128, 128, 128, 0.6);
      }
    }

    &.large {
      width: 56px;
      height: 56px;
      font-size: $font-size-lg;
    }

    .btn-icon {
      font-size: $font-size-lg;
    }

    .btn-text {
      font-size: $font-size-base;
      font-weight: $font-weight-semibold;
      font-family: $font-family;
    }

    .btn-label {
      font-size: 10px;
      font-weight: $font-weight-medium;
      font-family: $font-family;
      margin-top: 2px;
      line-height: 1;
    }
  }

  // 底部进度条
  .landscape-progress {
    position: absolute;
    bottom: 30px;
    left: 30px;
    right: 30px;
    pointer-events: auto;

    .progress-bar {
      height: 6px;
      background-color: rgba(255, 255, 255, 0.3);
      border-radius: 3px;
      overflow: hidden;
      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);

      .progress-fill {
        height: 100%;
        background-color: #007aff;
        border-radius: 3px;
        transition: width 0.3s ease;
      }
    }
  }
}

/* 操作提示 */
.reading-tip {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 200;

  .tip-content {
    background-color: rgba(0, 0, 0, 0.9);
    color: #fff;
    padding: 20px 30px;
    border-radius: 12px;
    text-align: center;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);

    .tip-text {
      display: block;
      font-size: 16px;
      margin-bottom: 10px;
      line-height: 1.5;
    }

    .tip-close {
      display: block;
      font-size: 14px;
      color: #007aff;
      opacity: 0.8;
    }
  }
}

/* 翻译结果显示 */
.translation-overlay {
  position: absolute;
  bottom: 100px;
  left: 30px;
  right: 30px;
  z-index: 150;
  pointer-events: auto;

  .translation-content {
    background: rgba(0, 0, 0, 0.9);
    backdrop-filter: blur(10px);
    border-radius: 12px;
    padding: 20px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);

    .translation-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 15px;

      .translation-title {
        color: #007aff;
        font-size: 16px;
        font-weight: 600;
      }

      .translation-close {
        width: 24px;
        height: 24px;
        border-radius: 12px;
        background: rgba(255, 255, 255, 0.2);
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;

        .close-icon {
          color: #fff;
          font-size: 18px;
          font-weight: bold;
        }

        &:active {
          background: rgba(255, 255, 255, 0.3);
        }
      }
    }

    .translation-text {
      color: #fff;
      font-size: 15px;
      line-height: 1.6;
      max-height: 120px;
      overflow-y: auto;
    }
  }
}

/* 翻译加载状态 */
.translation-loading {
  position: absolute;
  bottom: 100px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 150;
  pointer-events: auto;

  .loading-content {
    background: rgba(0, 0, 0, 0.8);
    backdrop-filter: blur(10px);
    border-radius: 20px;
    padding: 12px 24px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);

    .loading-text {
      color: #fff;
      font-size: 14px;
    }
  }
}

/* 文字阅读模式 */
.text-reading-mode {
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;

  .background-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    opacity: 0.15;
    filter: blur(1px);
    z-index: 1;
  }

  .text-content-area {
    position: relative;
    z-index: 2;
    width: 90%;
    max-width: 600px;
    max-height: 80%;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .text-content {
    width: 100%;
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(10px);
    border-radius: 20px;
    padding: 30px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);

    .text-wrapper {
      max-height: 400px;
      overflow-y: auto;

      .page-text {
        font-size: 18px;
        line-height: 1.8;
        color: #2c3e50;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
        font-weight: 500;
        text-align: justify;
        word-break: break-word;
        letter-spacing: 0.5px;
      }
    }
  }

  .no-text-tip {
    text-align: center;
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(10px);
    border-radius: 20px;
    padding: 40px 30px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);

    .tip-icon {
      font-size: 48px;
      margin-bottom: 16px;
      display: block;
    }

    .tip-text {
      display: block;
      font-size: 16px;
      color: #666;
      margin-bottom: 8px;
      font-weight: 500;
    }

    .tip-subtitle {
      display: block;
      font-size: 14px;
      color: #999;
      font-weight: 400;
    }
  }
}

/* 横屏模式下的文字阅读样式调整 */
.landscape {
  .text-reading-mode {
    .text-content-area {
      max-width: 70%;
      max-height: 70%;
    }

    .text-content {
      padding: 25px;

      .text-wrapper {
        max-height: 300px;

        .page-text {
          font-size: 16px;
          line-height: 1.7;
        }
      }
    }

    .no-text-tip {
      padding: 30px 25px;

      .tip-icon {
        font-size: 40px;
        margin-bottom: 12px;
      }
    }
  }
}

/* 录音状态覆盖层样式 */
.recording-overlay-simple {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 99999;
  pointer-events: auto;
}

.recording-content-simple {
  background: white;
  border-radius: 20px;
  padding: 30px;
  text-align: center;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
  pointer-events: auto;
  min-width: 280px;
}

/* 录音状态指示器 */
.recording-status-indicator {
  margin-bottom: 20px;

  .recording-pulse {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #ccc;
    margin: 0 auto 10px;

    &.active {
      background: #ff4444;
      animation: pulse 1.5s infinite;
    }
  }

  .status-text {
    font-size: 16px;
    color: #333;
    font-weight: 500;
  }
}

/* 录音时长显示 */
.recording-time-display {
  margin-bottom: 25px;

  .time-text {
    font-size: 24px;
    font-weight: bold;
    color: #333;
    font-family: 'Courier New', monospace;
  }
}

/* 录音控制按钮组 */
.recording-button-group {
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
}

.recording-control-btn {
  border: none;
  border-radius: 25px;
  padding: 12px 24px;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  min-width: 120px;
  transition: all 0.2s ease;

  &.pause-btn {
    background: #ffa500;
    color: white;

    &:active {
      background: #e6940a;
      transform: scale(0.95);
    }
  }

  &.resume-btn {
    background: #4CAF50;
    color: white;

    &:active {
      background: #45a049;
      transform: scale(0.95);
    }
  }

  &.stop-btn {
    background: #ff4444;
    color: white;

    &:active {
      background: #cc0000;
      transform: scale(0.95);
    }
  }
}

/* 脉冲动画 */
@keyframes pulse {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.2);
    opacity: 0.7;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

.recording-content {
  background: #fff;
  border-radius: 20px;
  padding: 40px 30px;
  max-width: 320px;
  width: 90%;
  text-align: center;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}

/* 录音状态指示器 */
.recording-indicator {
  margin-bottom: 30px;
}

.recording-pulse {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  background: #ff4444;
  margin: 0 auto 15px;
  position: relative;

  &.active {
    animation: pulse 1.5s infinite;
  }

  &::before {
    font-family: "iconfont" !important;
    content: "\e6af";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 32px;
  }
}

@keyframes pulse {
  0% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(255, 68, 68, 0.7);
  }
  70% {
    transform: scale(1.1);
    box-shadow: 0 0 0 20px rgba(255, 68, 68, 0);
  }
  100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(255, 68, 68, 0);
  }
}

.recording-status {
  font-size: 18px;
  font-weight: 600;
  color: #333;
}

/* 录音时长显示 */
.recording-duration {
  margin-bottom: 30px;
}

.duration-text {
  font-size: 32px;
  font-weight: 700;
  color: #ff4444;
  font-family: 'Courier New', monospace;
}

/* 音量可视化 */
.volume-visualizer {
  margin-bottom: 30px;
}

.volume-bars {
  display: flex;
  align-items: end;
  justify-content: center;
  height: 60px;
  gap: 3px;
}

.volume-bar {
  width: 4px;
  background: #e0e0e0;
  border-radius: 2px;
  transition: all 0.1s ease;

  &.active {
    background: linear-gradient(to top, #ff4444, #ff8888);
  }

  &:nth-child(1), &:nth-child(20) { height: 10px; }
  &:nth-child(2), &:nth-child(19) { height: 15px; }
  &:nth-child(3), &:nth-child(18) { height: 20px; }
  &:nth-child(4), &:nth-child(17) { height: 25px; }
  &:nth-child(5), &:nth-child(16) { height: 30px; }
  &:nth-child(6), &:nth-child(15) { height: 35px; }
  &:nth-child(7), &:nth-child(14) { height: 40px; }
  &:nth-child(8), &:nth-child(13) { height: 45px; }
  &:nth-child(9), &:nth-child(12) { height: 50px; }
  &:nth-child(10), &:nth-child(11) { height: 60px; }
}

/* 录音控制按钮 */
.recording-controls {
  display: flex;
  gap: 15px;
  justify-content: center;
  margin-bottom: 20px;
}

.control-button {
  padding: 12px 20px;
  border-radius: 25px;
  border: none;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  min-width: 80px;

  &.pause-btn {
    background: #ffa500;
    color: white;

    &:active {
      background: #e6940a;
      transform: scale(0.95);
    }
  }

  &.resume-btn {
    background: #4CAF50;
    color: white;

    &:active {
      background: #45a049;
      transform: scale(0.95);
    }
  }

  &.stop-btn {
    background: #f44336;
    color: white;

    &:active {
      background: #da190b;
      transform: scale(0.95);
    }
  }
}

.btn-text {
  font-size: 14px;
}

/* 录音质量指示 */
.recording-quality {
  .quality-text {
    font-size: 14px;
    color: #666;
    background: #f5f5f5;
    padding: 8px 16px;
    border-radius: 15px;
    display: inline-block;
  }
}

/* 录音按钮样式增强 */
.recording-btn {
  position: relative;
  transition: all 0.3s ease;

  &.recording {
    background: #ff4444 !important;
    animation: recording-pulse 2s infinite;

    .btn-icon {
      color: white;
    }
  }

  &.paused {
    background: #ffa500 !important;

    .btn-icon {
      color: white;
    }
  }

  .btn-label {
    position: absolute;
    bottom: -25px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 12px;
    color: #666;
    white-space: nowrap;
  }
}

@keyframes recording-pulse {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(255, 68, 68, 0.7);
  }
  50% {
    box-shadow: 0 0 0 10px rgba(255, 68, 68, 0);
  }
}





/* 覆盖层停止按钮特殊样式 */
.overlay-stop-btn {
  background: #ff4444 !important;
  color: white !important;
  border: 2px solid #fff !important;
  font-size: 18px !important;
  font-weight: bold !important;
  min-height: 50px !important;
  min-width: 120px !important;

  .btn-text {
    color: white !important;
    font-size: 16px !important;
    font-weight: bold !important;
  }

  &:active {
    background: #cc0000 !important;
    transform: scale(0.95);
  }
}

/* 新的覆盖层按钮样式 */
.overlay-stop-button {
  background: #ff4444;
  color: white;
  border: 2px solid #fff;
  border-radius: 25px;
  padding: 15px 25px;
  font-size: 18px;
  font-weight: bold;
  margin: 10px;
  min-width: 150px;
  cursor: pointer;

  &:active {
    background: #cc0000;
    transform: scale(0.95);
  }
}

.overlay-force-stop-button {
  background: #ff6666;
  color: white;
  border: 2px solid #fff;
  border-radius: 25px;
  padding: 15px 25px;
  font-size: 16px;
  font-weight: bold;
  margin: 10px;
  min-width: 150px;
  cursor: pointer;

  &:active {
    background: #cc3333;
    transform: scale(0.95);
  }
}

/* 自动阅读下一本对话框 */
.next-book-dialog {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;

  .dialog-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(4px);
  }

  .dialog-content {
    position: relative;
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(20px);
    border-radius: 20px;
    padding: 0;
    margin: 20px;
    max-width: 400px;
    width: 90%;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    border: 1px solid rgba(255, 255, 255, 0.3);
    overflow: hidden;

    .dialog-header {
      padding: 24px 24px 16px;
      text-align: center;
      border-bottom: 1px solid rgba(0, 0, 0, 0.1);

      .dialog-title {
        font-size: 18px;
        font-weight: 600;
        color: #2c3e50;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
      }
    }

    .dialog-body {
      padding: 20px 24px;

      .next-book-info {
        display: flex;
        align-items: center;
        margin-bottom: 20px;

        .next-book-cover {
          width: 60px;
          height: 80px;
          border-radius: 8px;
          margin-right: 16px;
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
        }

        .next-book-details {
          flex: 1;

          .next-book-title {
            display: block;
            font-size: 16px;
            font-weight: 600;
            color: #2c3e50;
            margin-bottom: 6px;
            line-height: 1.4;
          }

          .next-book-desc {
            display: block;
            font-size: 14px;
            color: #7f8c8d;
            line-height: 1.4;
            overflow: hidden;
            text-overflow: ellipsis;
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
          }
        }
      }

      .countdown-info {
        text-align: center;
        padding: 16px;
        background: rgba(52, 152, 219, 0.1);
        border-radius: 12px;
        border: 1px solid rgba(52, 152, 219, 0.2);

        .countdown-text {
          font-size: 15px;
          color: #3498db;
          font-weight: 500;
        }
      }
    }

    .dialog-actions {
      display: flex;
      border-top: 1px solid rgba(0, 0, 0, 0.1);

      .dialog-btn {
        flex: 1;
        padding: 16px;
        border: none;
        background: transparent;
        font-size: 16px;
        font-weight: 500;
        cursor: pointer;
        transition: background-color 0.2s ease;

        &.cancel-btn {
          color: #7f8c8d;
          border-right: 1px solid rgba(0, 0, 0, 0.1);

          &:active {
            background: rgba(0, 0, 0, 0.05);
          }
        }

        &.confirm-btn {
          color: #3498db;
          font-weight: 600;

          &:active {
            background: rgba(52, 152, 219, 0.1);
          }
        }
      }
    }
  }
}

/* 阅读完成选择对话框 */
.reading-complete-dialog {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;

  .dialog-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(4px);
  }

  .dialog-content {
    position: relative;
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(20px);
    border-radius: 20px;
    padding: 0;
    margin: 20px;
    max-width: 400px;
    width: 90%;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    border: 1px solid rgba(255, 255, 255, 0.3);
    overflow: hidden;

    .dialog-header {
      padding: 24px 24px 16px;
      text-align: center;
      border-bottom: 1px solid rgba(0, 0, 0, 0.1);

      .dialog-title {
        font-size: 20px;
        font-weight: 600;
        color: #2c3e50;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
      }
    }

    .dialog-body {
      padding: 20px 24px;
      text-align: center;

      .complete-message {
        display: block;
        font-size: 16px;
        color: #2c3e50;
        margin-bottom: 12px;
        line-height: 1.5;
        font-weight: 500;
      }

      .complete-subtitle {
        display: block;
        font-size: 14px;
        color: #7f8c8d;
        margin-bottom: 20px;
        line-height: 1.4;
      }
    }

    .dialog-actions {
      display: flex;
      flex-direction: column;
      border-top: 1px solid rgba(0, 0, 0, 0.1);

      &.vertical {
        flex-direction: column;
      }

      .dialog-btn {
        padding: 16px 24px;
        border: none;
        background: transparent;
        font-size: 16px;
        font-weight: 500;
        cursor: pointer;
        transition: background-color 0.2s ease;
        border-bottom: 1px solid rgba(0, 0, 0, 0.1);

        &:last-child {
          border-bottom: none;
        }

        &.primary-btn {
          color: #3498db;
          font-weight: 600;

          &:active {
            background: rgba(52, 152, 219, 0.1);
          }
        }

        &.secondary-btn {
          color: #27ae60;
          font-weight: 600;

          &:active {
            background: rgba(39, 174, 96, 0.1);
          }
        }

        &.cancel-btn {
          color: #7f8c8d;

          &:active {
            background: rgba(0, 0, 0, 0.05);
          }
        }
      }
    }
  }
}

/* 现代化录音UI样式 */
.recording-overlay-modern {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.3);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  z-index: 99999;
  pointer-events: auto;
  padding-top: 100px;
}

.recording-card {
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
  border-radius: 20px;
  padding: 20px;
  text-align: center;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  pointer-events: auto;
  min-width: 200px;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

/* 录音波纹动画容器 */
.recording-wave-container {
  position: relative;
  width: 80px;
  height: 80px;
  margin: 0 auto 15px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.recording-wave-center {
  position: relative;
  z-index: 3;
  width: 50px;
  height: 50px;
  background: #ff4444;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 12px rgba(255, 68, 68, 0.3);
}

.recording-icon {
  font-size: 24px;
  color: white;
}

.recording-wave {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border: 2px solid #ff4444;
  border-radius: 50%;
  opacity: 0;

  &.active {
    animation: wave-pulse 2s infinite;
  }
}

@keyframes wave-pulse {
  0% {
    width: 50px;
    height: 50px;
    opacity: 1;
  }
  100% {
    width: 80px;
    height: 80px;
    opacity: 0;
  }
}

/* 录音信息 */
.recording-info {
  margin-bottom: 15px;
}

.recording-status {
  display: block;
  font-size: 16px;
  font-weight: 600;
  color: #333;
  margin-bottom: 5px;
}

.recording-time {
  display: block;
  font-size: 20px;
  font-weight: 700;
  color: #ff4444;
  font-family: 'Courier New', monospace;
}

/* 简化版录音控制按钮 */
.recording-controls-mini {
  display: flex;
  gap: 10px;
  justify-content: center;
}

.control-btn-mini {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

  &.pause {
    background: #ff9500;
  }

  &.resume {
    background: #34c759;
  }

  &.stop {
    background: #ff3b30;
  }

  &:hover {
    transform: scale(1.1);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  }
}

.btn-icon-mini {
  font-size: 16px;
  color: white;
}

/* 录音预览界面样式 */
.recording-preview-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 99999;
  pointer-events: auto;
}

.preview-card {
  background: white;
  border-radius: 20px;
  padding: 30px;
  text-align: center;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
  pointer-events: auto;
  min-width: 300px;
  max-width: 400px;
}

.preview-header {
  margin-bottom: 25px;
}

.preview-title {
  display: block;
  font-size: 20px;
  font-weight: 600;
  color: #333;
  margin-bottom: 8px;
}

.preview-duration {
  display: block;
  font-size: 24px;
  font-weight: 700;
  color: #ff4444;
  font-family: 'Courier New', monospace;
}

.preview-controls {
  display: flex;
  gap: 15px;
  justify-content: center;
  margin-bottom: 25px;
}

.preview-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 15px;
  border-radius: 15px;
  cursor: pointer;
  transition: all 0.3s ease;
  min-width: 80px;

  &.play-btn {
    background: #f0f9ff;
    border: 2px solid #3b82f6;

    &.playing {
      background: #3b82f6;

      .btn-icon, .btn-text {
        color: white;
      }
    }

    .btn-icon, .btn-text {
      color: #3b82f6;
    }
  }

  &.rerecord-btn {
    background: #fef3f2;
    border: 2px solid #ef4444;

    .btn-icon, .btn-text {
      color: #ef4444;
    }

    &:hover {
      background: #ef4444;

      .btn-icon, .btn-text {
        color: white;
      }
    }
  }

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  }
}

.btn-icon {
  font-size: 24px;
}

.btn-text {
  font-size: 14px;
  font-weight: 500;
}

.preview-actions {
  display: flex;
  gap: 15px;
  justify-content: center;
}

.action-btn {
  flex: 1;
  padding: 12px 20px;
  border-radius: 25px;
  cursor: pointer;
  transition: all 0.3s ease;

  &.cancel-btn {
    background: #f5f5f5;
    border: 1px solid #ddd;

    .action-text {
      color: #666;
    }

    &:hover {
      background: #e5e5e5;
    }
  }

  &.confirm-btn {
    background: #34c759;
    border: 1px solid #34c759;

    .action-text {
      color: white;
    }

    &:hover {
      background: #2fb344;
    }
  }
}

.action-text {
  font-size: 16px;
  font-weight: 600;
}

/* 错误状态样式 */
.error-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f8f9fa;
  z-index: 100;
}

.error-content {
  text-align: center;
  padding: 40px 20px;
  max-width: 400px;
}

.error-icon {
  font-size: 64px;
  margin-bottom: 20px;
}

.error-title {
  font-size: 24px;
  font-weight: 600;
  color: #333;
  margin-bottom: 12px;
}

.error-message {
  font-size: 16px;
  color: #666;
  margin-bottom: 30px;
  line-height: 1.5;
}

.error-actions {
  display: flex;
  gap: 15px;
  justify-content: center;
}

.retry-btn, .back-btn {
  padding: 12px 24px;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 500;
  border: none;
  cursor: pointer;
  transition: all 0.3s ease;
}

.retry-btn {
  background: #3b82f6;
  color: white;

  &:hover {
    background: #2563eb;
  }
}

.back-btn {
  background: #f3f4f6;
  color: #374151;

  &:hover {
    background: #e5e7eb;
  }
}

.iconfont{
  color: white;
  // font-size: 100px;
}

/* 控制栏淡出动画 */
.fade-out-animation {
  animation: fadeOut 0.3s ease-out forwards;
}

@keyframes fadeOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

/* 控制栏淡入动画 */
.landscape-controls,
.page-controls,
.custom-navbar {
  transition: opacity 0.3s ease-in-out;
}

/* 只移除蓝色高亮效果，保留点击动画 */
button,
.control-btn,
.control-btn-mini,
.preview-btn,
.action-btn,
.dialog-btn,
view,
text,
image {
  /* 只移除点击高亮，保留其他交互效果 */
  -webkit-tap-highlight-color: transparent;
}
</style>
